在我当前的项目中,几个视图控制器(如vc
)生成在静态 NSOperationQueue 上执行的 NSOperation 对象(如operation
)。当操作等待或运行时,它将通过委托(operation.delegate = vc
,分配不保留)向视图控制器报告。
但是这些操作可能需要一段时间,同时应用程序可以释放视图控制器(通过将它们从导航控制器的堆栈中弹出)。
到目前为止,一切都是故意的。包含静态 NSOperationQueue 的类有办法返回操作,因此视图控制器不会保留它们。它们只是分配/初始化/自动释放并放入队列中。
现在这也导致了问题。在视图控制器解除分配后,对 NSOperation 的精神委托的任何调用都将导致错误的访问冲突。据我了解,无法检查指针处的对象是否已被释放,如本问题所述。
我能想到的一种解决方法是保留操作并将 operation.delegate 设置为 nil on dealloc。但这将是我最不受欢迎的修复,因为它会引入很多额外的 ivars/属性来跟踪。
因此,我的问题是,有没有其他方法可以解决这个问题,如果有,你能在这里画一个吗?
干杯,
EP。
解决方案:最适合我的方法是与 Guiliano 的回答略有不同:
在队列管理器中实现每个委托协议是不可行的(20 多种不同的协议和 50 多种方法),所以我保留了直接委托分配。我所做的更改是进行分配调用的班级。这曾经是创建请求的类(和委托),但现在它被卸载到队列管理器。
队列管理器除了将委托分配给操作之外,还拥有一个辅助可变字典来跟踪委托/操作对。
每个委托实例在释放时调用一个
[QueueManager invalidateDelegate:self]
方法,然后查找属于该委托的请求并将其归零。然后还删除字典操作/委托对以允许正确解除分配操作。最后,通过 KVO 观察
isFinished
每个操作的属性,可变 dict 保持干净,以确保所有操作保留计数在完成后实际释放。
感谢 Guiliano 提供使用 KVO 破解此问题的提示!