在我目前的项目中,几个视图控制器(如vc
)产生在静态NSOperationQueue上执行的NSOperation对象(如operation
)。当操作正在等待或运行时,它将通过委派报告给视图控制器(operation.delegate = vc
,分配未保留)。如何正确处理一个排队代理的排队nsoperation
虽然这些操作可能需要一段时间,但同时应用程序可以通过弹出导航控制器的堆栈来释放视图控制器。
到目前为止,一切都是故意的。包含静态NSOperationQueue的类有办法恢复操作,因此视图控制器不保留它们。他们只是alloc/init/autoreleased并放在队列中。
现在,这也会导致问题。在视图控制器释放后,任何对NSOperation的激进委托的调用都会导致访问冲突。据我所知,不可能检查指针上的对象是否已被释放,as stated in this question。
我能想到的一个修复方法是保留操作并将操作设置为dealloc。但那是我最不喜欢的解决方案,因为它会引入很多额外的ivars /属性来跟踪。
因此,我的问题是,还有其他方法来解决这个问题,如果是的话,你能在这里画一个吗?
干杯,
EP。
SOLUTION:制定出最适合我的方法是朱利安诺的回答略有变化:
实现队列管理器每个代表协议是不可行的(20个+不同的协议与50+方法),所以我保留了直接委托分配。我所做的改变是让班级进行分配。这曾经是创建请求的类(和委托),但现在它被卸载到队列管理器。
队列管理器在将委托分配给操作旁边还包含辅助可变字典以跟踪委托/操作对。
每个委托实例在释放时调用
[QueueManager invalidateDelegate:self]
方法,然后查找属于该委托的请求并将其删除。然后字典操作/委托对也被删除,以允许适当地释放该操作。最后,在KVO观察每个操作的
isFinished
属性后,可变字典保持清晰,以确保所有操作保留计数实际上在完成后释放。
感谢Guiliano提供了使用KVO来解决这个问题的提示!
+1其次。它还可以更容易地“重新连接”到vc,以防再次出现并需要响应队列(及其内容)中的更改。 – Toastor 2011-05-06 17:04:29
非常有趣的方法。它将使QueueManager(确实存在)更加复杂一点,但它也将使代表团更加健壮。我会让它腌一下,但听起来像是要走的路。 – epologee 2011-05-06 17:24:59
如果您需要一些示例代码,请参阅Apple文档中的FetchedImageLinker示例代码。有一个名为WatchedOperationQueue的类(或类似的东西,这里没有文档)实现了描述的行为。 – 2011-05-06 19:48:32