I have an App where I transferred a Complex UIViewController Xib and supporting code from a completely functioning App. The structure of the new VC is:
VC.view (defined in Interface Builder)
subView[0] StackView
subView[1] StackView
subview[2] UIView
based on an argument passed to the VC in prepareForSegue, the subView[2] UIView contains any of three programmatically defined collectionViews. On testing all of these subviews get defined properly. After initializing, they display properly with Xcode Quicklook.
A crash occurs after viewWillAppear(), and in-between viewIsAppearing() and viewDidAppear. The stack trace, below appears to indicate something wrong in a [UILabel drawTextInRect]:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull set]: unrecognized selector sent to instance 0x7ff86002efd0'
*** First throw call stack:
(
0 CoreFoundation 0x00007ff80048d28d __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007ff800057894 objc_exception_throw + 48
2 CoreFoundation 0x00007ff8004a23a3 +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0
3 CoreFoundation 0x00007ff800491a20 ___forwarding___ + 1459
4 CoreFoundation 0x00007ff800493c28 _CF_forwarding_prep_0 + 120
5 UIFoundation 0x00007ff804ad8ff1 -[NSCoreTypesetter _NSFastDrawString:length:attributes:paragraphStyle:typesetterBehavior:lineBreakMode:rect:padding:graphicsContext:baselineRendering:usesFontLeading:usesScreenFont:scrollable:syn 6 UIFoundation 0x00007ff804adb9b2 -[NSCoreTypesetter _stringDrawingCoreTextEngineWithOriginalString:rect:padding:graphicsContext:forceClipping:attributes:stringDrawingOptions:drawingContext:stringDrawingInterface:] + 1478
7 UIFoundation 0x00007ff804ad2ece __NSStringDrawingEngine + 2125
8 UIFoundation 0x00007ff804ad06e9 _NSStringDrawingCore + 173
9 UIFoundation 0x00007ff804ad4017 -[NSAttributedString(NSExtendedStringDrawing) drawWithRect:options:context:] + 91
10 UIKitCore 0x00000001147d5b6e -[UILabel _drawTextInRect:baselineCalculationOnly:returningDeviceMetricsOfFirstLine:forceMultiline:] + 5410
11 UIKitCore 0x00000001147d6d80 -[UILabel _drawTextInRect:forceMultiline:] + 41
12 UIKitCore 0x00000001147d6d4d -[UILabel _drawTextInRect:] + 43
13 UIKitCore 0x00000001147d41e2 -[UILabel drawTextInRect:] + 612
14 UIKitCore 0x00000001147d6e2c -[UILabel drawRect:] + 103
15 UIKitCore 0x00000001148a8206 -[UIView(CALayerDelegate) drawLayer:inContext:] + 610
16 QuartzCore 0x00007ff808e27725 CABackingStoreUpdate_ + 243
17 QuartzCore 0x00007ff808ff3c1d ___ZN2CA5Layer8display_Ev_block_invoke + 53
18 QuartzCore 0x00007ff808fe9f23 -[CALayer _display] + 2167
19 QuartzCore 0x00007ff808ffda58 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 472
20 QuartzCore 0x00007ff808eff2f4 _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 706
21 QuartzCore 0x00007ff808f3984a _ZN2CA11Transaction6commitEv + 728
22 QuartzCore 0x00007ff808f3ad3a _ZN2CA11Transaction25flush_as_runloop_observerEb + 60
23 CoreFoundation 0x00007ff8003e8d94 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
24 CoreFoundation 0x00007ff8003e372a __CFRunLoopDoObservers + 534
25 CoreFoundation 0x00007ff8003e3c72 __CFRunLoopRun + 1158
26 CoreFoundation 0x00007ff8003e3409 CFRunLoopRunSpecific + 557
27 GraphicsServices 0x00007ff80a648187 GSEventRunModal + 137
28 UIKitCore 0x00000001141dc672 -[UIApplication _run] + 972
29 UIKitCore 0x00000001141e10e0 UIApplicationMain + 123
So I put Symbolic Breakpoints on UILabel.setText and UILabel.drawTextInRect All the setTexts appear fine, and the printouts of $arg1 on the drawTextInRect show the last pass through with filling a segmented control label (which is in subView[1]. Here is a partial listing of the arg1's:
<UILabel: 0x117a68220; frame = (62 15; 20 20.3333); text = 'B'; userInteractionEnabled = NO; backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <_UILabelLayer: 0x600002673ba0>>
<UILabel: 0x117a67c90; frame = (10 8; 53 34); text = 'A'; userInteractionEnabled = NO; backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <_UILabelLayer: 0x6000026732a0>>
<UISegmentLabel: 0x117a61690; frame = (24.3333 9.33333; 36.3333 15.6667); text = 'TextABC'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x600002670c00>>
The crash occurs one instruction step after the end of viewIsAppearing. Is there a way to determine what method "instance 0x7ff86002efd0" is? The segue is a standard:
performSegue(withIdentifier: "segueToSelectGlyphVC", sender: nil)
The prepareForSegue correctly finds the new VC and loads some Strings vars into it.
From here, how can I further trace down what the issue is with the system trying to call NSNull with a bad selector? All of the outlets defined in the Xib appear to be properly connected to the swift code files. Thanks!
The stack trace indicates that an attributed string is being drawn at the time of the crash. The error is about trying to call the set
method on an instance of NSNull
. The set
method comes from UIColor
. The fact that there is an NSNull
instance instead of a UIColor
instance suggests that some color-related attribute of the attributed string is somehow nil
instead of a valid UIColor
instance.
So the solution is to find where in your storyboard or where in some code you are inadvertently setting an invalid color on an attributed string. Once you fix the color reference, the crash should be resolved.