为什么iPhone OS 3.1上的NSOperationQueue会持续长时间取消(和发布)的操作?

qwz*_*bug 6 iphone crash networking nsoperation iphone-sdk-3.1

我有一个NSOperations用于管理对Web API的服务调用的应用程序(这些调用基于Jon Wight的触摸代码中的CURLOperation).

当地图视图的中心发生显着变化时,会有一个下载地图位置的调用; 因为这些可以如此快速地叠加,如果你移动地图,我会尝试积极地取消陈旧的操作.它在4.0上运行良好.

但是,在3.1上,似乎在某些情况下操作队列将保持取消(和释放)操作,当它到达应该在队列中的位置时导致崩溃.

这是一个例子.

我从队列中相对较重的服务调用开始:

  1. MyLongRunningOp 0x1

用户导航到地图.队列现在看起来像这样:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

他们移动地图,取消MyMapOp 0x2并添加MyMapOp 0x3:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x3

MyMapOp 0x2现已发布,因为它已从队列中删除.现在MyLongRunningOp 0x1结束了.在用于设置isFinished键的KVO回调中MyLongRunningOp,我看到操作队列处理通知并尝试添加MyMapOp 0x2到某些通知NSArray.当然,NSZombies启用后,

[MyMapOp retain]: message sent to deallocated instance 0x2
Run Code Online (Sandbox Code Playgroud)

它似乎NSOperationQueue以某种方式挂在指向取消/释放操作的指针上,并在先前操作完成后尝试激活它.

我无法在4.0上重现此行为,因此我认为这是一个3.1错误.

我在解决它时遇到了很多麻烦 - 据我所知,唯一的解决方法是永远不要取消我的操作,这会在网络变得不确定时产生欠佳的体验.

还有其他人经历过这个吗?有任何想法吗?

小智 1

我在 NSOperations 上使用 KVO 时遇到了(我认为是)类似的问题。

只是阅读您的描述,我的第一直觉是检查操作队列的规则。是否有可能一旦您将其交给队列,队列就应该承担所有权,因此您不应该手动释放它?(不确定你是否是)。

从我个人的经验来看,也许这会有所帮助,也可能没有帮助:

1)当你取消一个op时,从其中删除KVO观察者。我遇到过这样的情况:当任何一方被删除时,KVO 都不会取消链接。

2) 请注意,KVO 回调与 NSOperation 在同一线程中运行。因此,在您开始操作和 KVO 回调之间,对象可能会超出范围。

如果您发布代码,我也许可以为您提供更多帮助。希望以上内容对您有用!