I am independently going through the Programming iOS 7 course on iTunes U from Stanford, and therefore now that I have a question and I can't ask the teacher, I'm hoping someone here can help me out. Ideally by telling me how to track down this type of problem, but I'm also posting my entire project at http://talix.homeip.net/2014/Matchismo.zip (since I don't think I can usefully post the UI for you to debug it in this post like normal text code), so just telling me where specifically the problem is would be very much appreciated as well! I'm in the middle of assignment 3 for anyone who has taken the same course.
I've got a very basic card matching game that can play with playing cards or "Set". The playing card tab works great. The Set tab crashes with an uncaught exception (copied below) as soon as I press the New Game button or click on a card (which results in starting a new game). I have put a breakpoint in my code so that I catch the New Game action, and stepped through all of the resulting code. It all seems to work fine when I am stepping through my code. When I reach the end of the last of my functions that get called as a result of the action, and then I press Continue in XCode, that's when it crashes. Given that fact, I'm not sure how to trace what exactly is causing the problem.
Another question: Is it useful to post the entire call stack from the exception text, or are the top couple lines the only really useful ones (for beginners like me at least)? I think I see that the unrecognized selector in question is [__NSCFConstantString _isDefaultFace]:, but I don't know where that would be getting called as part of what I'm assuming is UI code behind the types of classes I use (UILabel, etc.).
Here is the whole exception text just in case:
2014-09-28 18:45:54.337 Matchismo[17292:2714082] -[__NSCFConstantString _isDefaultFace]: unrecognized selector sent to instance 0xc721c
2014-09-28 18:45:54.346 Matchismo[17292:2714082] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString _isDefaultFace]: unrecognized selector sent to instance 0xc721c'
*** First throw call stack:
(
0 CoreFoundation 0x01cfddf6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x01987a97 objc_exception_throw + 44
2 CoreFoundation 0x01d05a75 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x01c4e9c7 ___forwarding___ + 1047
4 CoreFoundation 0x01c4e58e _CF_forwarding_prep_0 + 14
5 UIFoundation 0x0355a1a9 -[NSMutableAttributedString(NSMutableAttributedStringKitAdditions) fixFontAttributeInRange:] + 2593
6 UIFoundation 0x035596b6 -[NSMutableAttributedString(NSMutableAttributedStringKitAdditions) fixAttributesInRange:] + 132
7 UIFoundation 0x0356b371 __NSStringDrawingEngine + 6661
8 UIFoundation 0x03571c00 -[NSAttributedString(NSExtendedStringDrawing) boundingRectWithSize:options:context:] + 1311
9 UIKit 0x0068fd5e -[UIButton _intrinsicSizeWithinSize:] + 825
10 UIKit 0x00ae4be6 -[UIView(UIConstraintBasedLayout) intrinsicContentSize] + 51
11 UIKit 0x00ae51e5 -[UIView(UIConstraintBasedLayout) _generateContentSizeConstraints] + 36
12 UIKit 0x00ae4f16 -[UIView(UIConstraintBasedLayout) _updateContentSizeConstraints] + 505
13 UIKit 0x00aed1aa -[UIView(AdditionalLayoutSupport) updateConstraints] + 185
14 UIKit 0x0068f7e1 -[UIButton updateConstraints] + 3366
15 UIKit 0x00aec614 -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 259
16 UIKit 0x00aec861 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 127
17 UIKit 0x00aec7dc __UIViewRecursionHelper + 41
18 CoreFoundation 0x01bf29b9 CFArrayApplyFunction + 57
19 UIKit 0x00aec5af -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 158
20 UIKit 0x00aec894 __125-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:]_block_invoke + 43
21 Foundation 0x015766f7 -[NSISEngine withBehaviors:performModifications:] + 150
22 Foundation 0x01579c4f -[NSISEngine withAutomaticOptimizationDisabled:] + 48
23 UIKit 0x00aec3fb -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 64
24 UIKit 0x00aec861 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 127
25 UIKit 0x00aecdf6 __60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 105
26 Foundation 0x015766f7 -[NSISEngine withBehaviors:performModifications:] + 150
27 Foundation 0x01579c4f -[NSISEngine withAutomaticOptimizationDisabled:] + 48
28 UIKit 0x00aec3fb -[UIView(AdditionalLayoutSupport) _withAutomaticEngineOptimizationDisabledIfEngineExists:] + 64
29 UIKit 0x00aeca4c -[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded] + 248
30 UIKit 0x00aed27e -[UIView(AdditionalLayoutSupport) _updateConstraintsAtEngineLevelIfNeeded] + 170
31 UIKit 0x003eec9e -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 120
32 UIKit 0x003eef9c -[UIView(Hierarchy) layoutSubviews] + 57
33 UIKit 0x003fc9c0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 608
34 libobjc.A.dylib 0x0199d771 -[NSObject performSelector:withObject:] + 70
35 QuartzCore 0x0462227f -[CALayer layoutSublayers] + 152
36 QuartzCore 0x04616105 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 397
37 QuartzCore 0x04615f60 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
38 QuartzCore 0x04574676 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 284
39 QuartzCore 0x04575a3c _ZN2CA11Transaction6commitEv + 392
40 QuartzCore 0x0463b789 +[CATransaction flush] + 52
41 UIKit 0x0036e0d3 _UIApplicationHandleEventQueue + 2296
42 CoreFoundation 0x01c217bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
43 CoreFoundation 0x01c172cd __CFRunLoopDoSources0 + 253
44 CoreFoundation 0x01c16828 __CFRunLoopRun + 952
45 CoreFoundation 0x01c161ab CFRunLoopRunSpecific + 443
46 CoreFoundation 0x01c15fdb CFRunLoopRunInMode + 123
47 GraphicsServices 0x0415024f GSEventRunModal + 192
48 GraphicsServices 0x0415008c GSEventRun + 104
49 UIKit 0x00371e16 UIApplicationMain + 1526
50 Matchismo 0x000bd80d main + 141
51 libdyld.dylib 0x022d0ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
It looks like I can't mark Hot Licks's comment as an answer to give reputation and mark it as the accepted answer, so I will put my own "answer" down here - but he should get the credit! :-)
The problem was I was passing an NSString as the NSFontAttributeName of an NSAttributedString, rather than an UIFont object. Here is the old offending code:
return [[NSAttributedString alloc] initWithString:text attributes:@{NSForegroundColorAttributeName : color,
NSStrokeColorAttributeName : color,
NSStrokeWidthAttributeName : strokeWidth,
NSFontAttributeName : @"System 12.0"}];
And here is the corrected code:
UIFont *font = [UIFont boldSystemFontOfSize:12];
return [[NSAttributedString alloc] initWithString:text attributes:@{NSForegroundColorAttributeName : color,
NSStrokeColorAttributeName : color,
NSStrokeWidthAttributeName : strokeWidth,
NSFontAttributeName : font}];
In retrospect, an obvious mistake, but aren't they always in hindsight? 😉 This is my first time using NSAttributedString, so hopefully I won't make the same mistake again in the future. Thanks again, Hot Licks!
My more long-term and serious question remains: why didn't this code crash when I stepped over it in the debugger, so that I would know what line to focus on?