如何了解哪个无法识别的选择器发送到实例
Posted
技术标签:
【中文标题】如何了解哪个无法识别的选择器发送到实例【英文标题】:How to understand which unrecognized selector sent to instance 【发布时间】:2014-03-26 10:44:09 【问题描述】:我如何从这个错误消息中找出这是哪个选择器?
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x178059b30'
如何让 xcode 给我正常的错误消息,告诉我问题出在哪里?
【问题讨论】:
它在错误消息中说明发送了什么消息,以及发送到什么样的对象。只需仔细阅读信息并动动您的大脑。仔细想想,这就是你问题的准确和正确答案。 错误消息说无法识别的选择器已发送到 NSArray,当我放置断点异常时,无法识别的选择器来自通过 xib 连接的 UILabel 并落在此行 [_label setText:name] , _label 不是零,“名称”也不是,所以问题是什么,为什么它会下降???当错误在标签 setText 行中时,为什么它说错误在 NSArray 中?length
是NSString
的一个方法。所以我猜name
实际上是NSArray
而不是NSString
,因为它应该是。当您使用 setText:
分配数组时,标签会调用特定于字符串的方法。
你有内存问题,一些悬空指针或提前释放的对象。
【参考方案1】:
这是一条正常的错误消息。系统不能告诉你更多。
但是在调试器的帮助下(启用异常断点),以及对 Objective-C 的良好理解,您应该能够诊断问题。
这是我们从异常消息中了解到的:
-
无法识别的选择器是
length
。具有此方法的最常见类是NSString
。
接收此方法的对象是NSArray
触发异常断点后,在调试器中输入po 0x178059b30
以检查数组。该数组的内容可以提示您找出问题最初是如何引起的。
从代码中的调试器位置,您可以看到触发错误的原因。
您说您的代码在[_label setText:name]
失败。
这个方法需要一个 NSString,在赋值过程中会调用几个 NSString 特定的方法,length
是这些方法之一。这证实了我们的猜测之一。
有两种可能:
name
实际上是一个 NSArray,因为您编写的代码分配了错误的对象。如果您不检查从字典或数组中获得的结果,通常会发生这种情况。
你有一个内存问题,name
被提前释放,数组现在是 NSString 应该在的位置。
要排除第二个选项,通常运行分析器就足够了。它将指出大多数内存问题。
另一种方法来确定这两者中哪一个更有可能使用po 0x178059b30
的输出。如果数组包含与 name
的预期值相关的对象(例如,它实际上包含 name
),则很有可能您确实分配了错误的对象。在这种情况下,请查看您设置名称的位置,并检查它。
如果你使用一个属性,你可以使用这样的东西来找出你在哪里分配了错误的对象:
- (void)setName:(NSString *)name
_name = [name copy];
if (![name isKindOfClass:[NSString class]])
NSAssert(NO, @"Wrong class %@", name);
当分配的对象不是 NSString 实例时将触发断点,您可以检查调用堆栈以查看您在哪里做错了。 确保在完成调试后删除该代码。您不得使用此类检查来防止代码中的错误。
【讨论】:
以上是关于如何了解哪个无法识别的选择器发送到实例的主要内容,如果未能解决你的问题,请参考以下文章
NSInvalidArgumentException,使用 performSegueWithIdentifier 时发送到实例的无法识别的选择器