如何调试“未识别的选择器发送到实例”错误

104

我正在为我的表视图创建自定义表格单元格视图。当我将故事板中的自定义单元格的图像视图连接到Swift代码时,我会得到以下错误。

[UITableViewCellContentView image]: unrecognized selector sent to instance 0x7fb4fad7fd20'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ccbb3f5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010e7e9bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010ccc250d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010cc1a7fc ___forwarding___ + 988
    4   CoreFoundation                      0x000000010cc1a398 _CF_forwarding_prep_0 + 120
    5   UIKit                               0x000000010d7d8881 -[UITableViewCell _marginWidth] + 151
    6   UIKit                               0x000000010d7ca23d -[UITableViewCell _separatorFrame] + 70
    7   UIKit                               0x000000010d7ca6fa -[UITableViewCell _updateSeparatorContent] + 360
    8   UIKit                               0x000000010d7d4e85 -[UITableViewCell _setSectionLocation:animated:forceBackgroundSetup:] + 1174
    9   UIKit                               0x000000010d634ea8 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1822
    10  UIKit                               0x000000010d5b5eae +[UIView(Animation) performWithoutAnimation:] + 65
    11  UIKit                               0x000000010d63477b -[UITableView _configureCellForDisplay:forIndexPath:] + 312
    12  UIKit                               0x000000010d63bcec -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 533
    13  UIKit                               0x000000010d61b7f1 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2846
    14  UIKit                               0x000000010d63165c -[UITableView layoutSubviews] + 213
    15  UIKit                               0x000000010d5be199 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
    16  QuartzCore                          0x00000001114b6f98 -[CALayer layoutSublayers] + 150
    17  QuartzCore                          0x00000001114abbbe _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    18  QuartzCore                          0x00000001114aba2e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    19  QuartzCore                          0x0000000111419ade _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
    20  QuartzCore                          0x000000011141abea _ZN2CA11Transaction6commitEv + 390
    21  QuartzCore                          0x000000011141b255 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
    22  CoreFoundation                      0x000000010cbf0347 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    23  CoreFoundation                      0x000000010cbf02a0 __CFRunLoopDoObservers + 368
    24  CoreFoundation                      0x000000010cbe60d3 __CFRunLoopRun + 1123
    25  CoreFoundation                      0x000000010cbe5a06 CFRunLoopRunSpecific + 470
    26  GraphicsServices                    0x0000000110daa9f0 GSEventRunModal + 161
    27  UIKit                               0x000000010d545550 UIApplicationMain + 1282
    28  TestWork                          0x000000010caa432e top_level_code + 78
    29  TestWork                          0x000000010caa436a main + 42
    30  libdyld.dylib                       0x000000010efc3145 start + 1
    31  ???                                 0x0000000000000001 0x0 + 1
)

请问你能告诉我如何解决这个错误吗?

谢谢。

我在我的项目中添加了一个异常断点。

这是它中断的那一行。

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as ItemTableViewCell  <---------------

但是我在我的代码中没有使用“image”。


2
你在某个地方调用了 image],但是对象错误。错误的第一行告诉你这一点。 - chasew
1
停止在UITableViewCellContentView上调用[image] - 这样可以解决问题。请向我们展示导致此崩溃的代码。 - Grzegorz Krukowski
1
我认为您在tableViewCell中使用了一些图像,但该图像可能不在您的捆绑包中。 - Nand Parikh
9个回答

102
尝试在-[NSObject(NSObject) doesNotRecognizeSelector:]上设置一个符号性断点。只需单击断点导航器左下角的[+]即可添加断点。然后点击“添加符号性断点”。现在复现崩溃应该会让你更好地了解问题出现在你的代码中的哪个位置。

18
也可以添加一个异常断点 - rebello95

39

你可以使用 异常断点 方便地跟踪此类崩溃。

打开 断点导航器 并添加

enter image description here

添加异常断点后,可以选择要捕捉的 异常

enter image description here

选择 Objective-C

运行代码并使应用程序崩溃,断点将停止在代码崩溃的位置。


1
发生在AppDelegate第1行。现在怎么办?:( - user5306470
你能展示一下你在AppDelegate中编写的代码吗?它在哪里暂停了断点?还有日志也一并展示。 - Vatsal K
它在第一行暂停,即应用程序委托被声明的位置。 - user5306470
有些情况下,由于一些框架的原因,应用程序会暂停,但不用担心,您可能需要按继续按钮3-4次才能运行应用程序。 - Vatsal K
在这种情况下,那不是错误,一些旧的框架导致了这种问题。尝试通过更新你的旧框架到新/更新的框架来解决这个问题。那应该可以解决问题。 - Vatsal K
我无法在没有看到代码的情况下诊断错误/警告。如果您能向我展示可疑的代码,那么我可以帮助您。 - Vatsal K

35

关键的第一步是分析错误信息:

[UITableViewCellContentView image]: unrecognized selector sent to instance

这告诉您“消息”image被“发送”到一个UITableViewCellContentView类对象中(换句话说,试图在UITableViewCellContentView类对象上调用image方法)。

首先要问的是“这是否有任何意义?” 可能是该命名类具有Image方法,但没有image方法,因此在调用时使用了错误的方法名称。 或者可能是所命名的方法是someMethod:someParm:,但该类实现了someMethod:someParm:anotherParm:,这意味着在调用时省略了参数。

然而,最常见的情况是所命名的类根本没有任何类似于所命名方法的方法,这意味着在失败的调用中使用了指向错误对象的指针。

例如,可能会执行以下操作:

NSArray* myArray = [myDictionary objectForKey:@"values"];
NSString* myString = [myArray objectAtIndex:5];

并且会得到类似以下内容的错误:

[__NSDictionaryI objectAtIndex:] unrecognized selector sent to instance

因为从 myDictionary 检索到的对象实际上是一个 NSDictionary,而不是预期的 NSArray,导致了混淆。

最令人困惑的是,当此类错误发生在 UI 系统代码中而不是您自己的代码中时。这可能会发生在您某些情况下错误地将对象传递给系统接口,或者在 Interface Builder 或其他位置配置了错误的类时。


6
另一个可能的原因是原始对象被销毁,然后在相同的内存地址上分配了另一个对象。然后你的代码发送了消息,认为它仍然有一个指向旧对象的指针,而 Objective-C 抛出异常,因为新对象不理解该消息。
要诊断此问题,请使用“僵尸”检测运行 Profiler。

3

Swift 5.0

您可以使用内省(Introspection)来查找对象是否响应特定的选择器。

let canWork = yourObject.respondsToSelector(Selector("image"))   // true

只有当代码是正确的时候,它才能正常工作。否则,它一定会崩溃。


1
您可以使用以下代码声明变量:
let noteListTableViewCellobject = "NoteListTableViewCell";` `// Note listTablecell create custom cell`

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell:NoteListTableViewCell? = tableView.dequeueReusableCellWithIdentifier(noteListTableViewCellobject) as? NoteListTableViewCell

    if (cell == nil) {
        let nib:Array = NSBundle.mainBundle().loadNibNamed("NoteListTableViewCell", owner: self, options: nil)
        cell = nib[0] as? NoteListTableViewCell
    }
}

1
在这些情况下,我发现查看两件事情很有帮助:
  1. 调用堆栈
  2. 每个堆栈帧中的本地变量(及其类型)
当我遇到此错误时,通常是因为我向 Type A 的实例发送了消息,而我期望的是 Type B。
在这种特定情况下,您可能未满足父类的要求(考虑到您的 ItemTableViewCell 实例很可能继承自该类)。
您能否向我们展示您的 ItemTableViewCell 类的代码?

0

你需要传递 indexPath 来声明 tableview cell 的对象。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

    return cell
}

0
我曾经遇到过同样的问题,这个方法对我很有用:
在你的SKScene中覆盖isEqual方法:
- (BOOL)isEqual:(id)other {

    if (![other isMemberOfClass:[SKScene class]]) {
        return false;
    }
    return [super isEqual:other];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接