我有一个NSOperation的子类,它将managedObject作为其属性之一。 我需要为nsoperationqueue&添加多个操作。观察他们的完成。 对于每个NSOperation实例,我创建了一个新的托管对象作为Apple文档状态“为每个线程创建一个单独的托管对象上下文并共享一个持久性存储协调器。”。 第一个操作完成后,我会得到以下崩溃日志
#0 0x34970c98 in objc_msgSend ()
#1 0x3608704e in -[_PFArray dealloc] ()
#2 0x36084b80 in -[_PFArray release] ()
#3 0x3179b1a0 in CFRelease ()
#4 0x3179deba in _CFAutoreleasePoolPop ()
#5 0x30d7bbb4 in NSPopAutoreleasePool ()
#6 0x30d91e1c in -[__NSOperationInternal start] ()
#7 0x30d91a7e in -[NSOperation start] ()
#8 0x30df7eca in ____startOperations_block_invoke_2 ()
#9 0x33a248e6 in _dispatch_call_block_and_release ()
#10 0x33a1a532 in _dispatch_worker_thread2 ()
#11 0x368bf590 in _pthread_wqthread ()
#12 0x368bfbc4 in start_wqthread ()
从日志中看来,某些对象正在过度发布。如何才能获得哪个对象过度释放? 应用程序使用NSZombieEnabled运行,但仅收到以上信息。 NsOperation是否维护自己的自动释放池?
答案 0 :(得分:0)
以下是您的线索:
#7 0x30d91a7e in -[NSOperation start] ()
这是你在手术中释放的东西。
#5 0x30d7bbb4 in NSPopAutoreleasePool ()
这是一个自动释放的对象。这并不一定意味着您已经编写了自动释放方法调用。由[NSString stringWithFormat:...]等便捷方法创建的对象在返回之前会自动释放。因此,在操作代码中查找要调用autorelease的位置,或者在没有alloc-init模式的情况下创建对象的位置。
是的,NSOperation维护自己的自动释放池。你不应该担心这一点。如果只在完成对象时释放对象,并且只在方法范围结束时完成自动释放对象(或者在返回方法时调用方法范围),那么你应该没问题。
#2 0x36084b80 in -[_PFArray release] ()
这是一个存储在数组(不是数组本身)中的对象,它被过度释放。
这种错误意味着您要么在不应该释放或自动释放对象,要么在应该的时候保留对象。它可能是不正确的版本或不正确的自动释放,即使自动释放池发生错误。自动释放可能是正确的,并且释放可能不正确。无论哪种方式,当自动释放池耗尽时都会发生错误,因为这会在以后发生。