Что вызывает мое непризнанное исключение селектора?

Я самостоятельно прохожу курс «Программирование iOS 7» в iTunes U из Стэнфорда, и поэтому теперь, когда у меня есть вопрос, и я не могу задать его учителю, я надеюсь, что кто-то здесь сможет мне помочь. В идеале, рассказав мне, как отследить проблему такого типа, но я также публикую весь свой проект по адресу http://talix.homeip.net/2014/Matchismo.zip (поскольку я не думаю, что смогу опубликовать пользовательский интерфейс для отладки в этом посте, как обычный текстовый код), так что просто скажите мне где конкретно проблема была бы очень признательна! Я в середине задания 3 для тех, кто прошел тот же курс.

У меня есть очень простая игра на сопоставление карт, в которую можно играть с игральными картами или «сетом». Вкладка игральных карт отлично работает. Вкладка «Набор» вылетает с необработанным исключением (скопировано ниже), как только я нажимаю кнопку «Новая игра» или нажимаю на карту (что приводит к началу новой игры). Я поставил точку останова в своем коде, чтобы поймать действие «Новая игра», и прошел через весь полученный код. Кажется, все работает нормально, когда я выполняю свой код. Когда я дохожу до конца последней из моих функций, которые вызываются в результате действия, а затем нажимаю «Продолжить» в XCode, происходит сбой. Учитывая этот факт, я не уверен, как отследить, что именно вызывает проблему.

Другой вопрос: полезно ли публиковать весь стек вызовов из текста исключения, или только верхние пару строк действительно полезны (по крайней мере, для новичков, таких как я)? Я думаю, что вижу, что рассматриваемый нераспознанный селектор [__NSCFConstantString _isDefaultFace]:, но я не знаю, где он будет вызываться как часть того, что я предполагаю, является кодом пользовательского интерфейса для типов классов, которые я использую (UILabel, и т.д.).

Вот весь текст исключения на всякий случай:

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

person Joe Morris    schedule 28.09.2014    source источник
comment
возможный дубликат Почему происходит сбой [NSTextStorage setAttributedString] с NSMutableAttributedString?   -  person Hot Licks    schedule 29.09.2014
comment
Вы должны передать объект шрифта, а не имя шрифта.   -  person Hot Licks    schedule 29.09.2014
comment
Спасибо большое, вы конечно правы! Как только вы указали на оскорбительную строку, я смог не только исправить ее, но и точно понять, почему она нуждалась в исправлении.   -  person Joe Morris    schedule 30.09.2014
comment
Я бы сказал, что не дубликат, потому что остается основной вопрос: почему мой код не падает, когда я перешагиваю через него в режиме отладки? Если бы он сделал это и, следовательно, указал, какая строка была проблемой, я, вероятно, смог бы понять это сам, не беспокоя вас, хорошие люди. Однако в следующий раз я постараюсь не забыть выполнить поиск на этом сайте именно с нераспознанным текстом селектора, а не просто с нераспознанным селектором, который я пробовал, и, конечно, это не очень помогло. ;-)   -  person Joe Morris    schedule 30.09.2014
comment
Кроме того, спасибо Полу Гриффитсу — я должен был подумать о том, чтобы поместить этот длинный текст исключения в блок кода, и я попытаюсь сделать это в будущем.   -  person Joe Morris    schedule 30.09.2014
comment
Ваш код не рухнул, когда вы переступили через него, потому что вы его не перешагнули. Как видно из трассировки стека, сбой происходит в логике отрисовки, которая автоматически выполняется системой, а не в вашем коде. Когда происходит отрисовка (или даже происходит ли она), это не связано с тем, где вы находитесь с отладчиком в вашей собственной логике.   -  person Hot Licks    schedule 30.09.2014
comment
(FWIW, приведенный выше обман был самым первым обращением, которое Google получил для _isDefaultFace.)   -  person Hot Licks    schedule 30.09.2014
comment
Ах, это имеет смысл @HotLicks, спасибо, даже если это разочаровывает с точки зрения простоты отладки. Я думал, что это перерисовка, когда я перешагнул линию, которая устанавливает текст кнопки. Как я уже упоминал, я новичок во всем этом, поэтому, хотя я прочитал трассировку стека, я не смог ее правильно интерпретировать.   -  person Joe Morris    schedule 02.10.2014


Ответы (1)


Похоже, я не могу пометить комментарий Hot Licks как ответ, чтобы повысить репутацию, и пометить его как принятый ответ, поэтому я оставлю здесь свой собственный «ответ», но он должен получить признание! :-)

Проблема заключалась в том, что я передавал NSString как NSFontAttributeName NSAttributedString, а не как объект UIFont. Вот старый оскорбительный код:

return [[NSAttributedString alloc] initWithString:text attributes:@{NSForegroundColorAttributeName : color,
                                                                    NSStrokeColorAttributeName : color,
                                                                    NSStrokeWidthAttributeName : strokeWidth,
                                                                    NSFontAttributeName : @"System 12.0"}];

А вот исправленный код:

UIFont *font = [UIFont boldSystemFontOfSize:12];
return [[NSAttributedString alloc] initWithString:text attributes:@{NSForegroundColorAttributeName : color,
                                                                    NSStrokeColorAttributeName : color,
                                                                    NSStrokeWidthAttributeName : strokeWidth,
                                                                    NSFontAttributeName : font}];

Оглядываясь назад, очевидная ошибка, но разве они не всегда оглядываются назад? ???? Это мой первый раз, когда я использую NSAttributedString, поэтому, надеюсь, я не повторю ту же ошибку в будущем. Еще раз спасибо, Hot Licks!

Мой более долгосрочный и серьезный вопрос остается: почему этот код не падает, когда я перешагиваю через него в отладчике, чтобы знать, на какой строке сосредоточиться?

person Joe Morris    schedule 30.09.2014
comment
Он не зависал, когда вы переступали через него, потому что initWithString не проверял его параметры строго, а просто сохранял значения. Этому способствовал тот факт, что параметры передавались как словарь атрибутов, а не отдельные параметры (что могло бы привести к предупреждающему сообщению компилятора). Objective-C и его библиотеки не особенно строго относятся к проверке параметров, по сравнению, скажем, с Java. - person Hot Licks; 02.10.2014