此崩溃的最可能原因是您正在向对象的已释放实例发送消息 - 尝试在启用 NSZomie 的情况下运行您的应用程序 - 请参阅如何在 Xcode 4 中设置 NSZombieEnabled?
发生的事情是,您的对象使用的内存在释放时被标记为未使用,并且在该位置分配了其他一些对象。但是,此对象属于不同的类,因此无法识别选择器消息。
正如评论中所指出的,向释放的实例发送消息的方式会有所不同:
该对象被分配在内存中的某处——在一个页面上,它被分配器分成几部分——例如malloc。如果底层分配器已经将对象所在的页面返回给内核,则应用程序将崩溃且没有日志 (EXC_BAD_ACCESS)。
如果对象被释放并且保留计数达到 0,它就会被释放,这意味着只是将页面上的内存标记为空闲以供将来使用。如果您因此尝试向该对象发送另一条消息,运行时将注意到该对象没有保留计数,因此已被释放并会处理message sent to deallocated instance
异常。
但是,如果您的初始对象占用的内存被介于两者之间的另一个对象占用,则运行时无法知道曾经有一个您打算调用方法的对象,因此出现unrecognized selector
异常,因为对象所属是对象结构的一部分——isa
指针。运行时没有(或可以)检查任何其他内容。对于运行时,向对象发送消息是一个有效的请求,但是,新对象上没有这样的方法。
如果新对象响应在一个类中执行致命操作的同一消息,则这可能是潜在的危险,因为如果该方法是有效的方法名称,则该方法实际上是在该对象上调用的!
当然,还有其他情况,例如对象将被其他数据覆盖,因此 isa 指针指向一个不存在的类,并且会像最初一样发生崩溃,因为操作系统将尝试取消引用一个地址在您的流程中无效。