Why does NSOperationQueue on iPhone OS 3.1 support lengthy (and released) operations?

I have an application that uses NSOperations to manage service calls in the web API (calls are based on CURLOperation in the Jon Wight touch code ).

There is a certain challenge that loads map locations when the map display center changes significantly; since they can add up so quickly if you move the map around, I am trying to aggressively cancel outdated operations. It works fine on 4.0.

However, in 3.1, it seems that in some cases the queue of operations will be held on the canceled (and issued) operations, which will lead to a failure in reaching the place where they should be in the queue.

Here is an illustration.

I start with a relatively heavy call to the service in the queue:

  • MyLongRunningOp 0x1

The user goes to the map. Now the queue looks like this:

  • MyLongRunningOp 0x1
  • MyMapOp 0x2

They move a map that cancels MyMapOp 0x2 and adds MyMapOp 0x3:

  • MyLongRunningOp 0x1
  • MyMapOp 0x3

MyMapOp 0x2 now freed because it has been removed from the queue. Now MyLongRunningOp 0x1 ends. In the KVO callbacks to set the isFinished key to MyLongRunningOp I see that the operation queue processes the notification and tries to add MyMapOp 0x2 to some NSArray . Naturally, with NSZombies turned NSZombies ,

 [MyMapOp retain]: message sent to deallocated instance 0x2 

It seems that NSOperationQueue somehow hangs on a pointer to a canceled / released operation and tries to activate it after the previous operation is completed.

I could not reproduce this behavior in 4.0, so I think this is a 3.1 error.

I have a lot of problems with him, as far as I can tell, the only workaround is to never cancel my operations, which leads to a non-optimal experience when the network becomes uncomfortable.

Has anyone else experienced this? Any ideas?

+6
iphone networking crash nsoperation
source share
1 answer

I had (I think a similar) problem using KVO on NSOperations.

Just by reading your description, my first instinct will be checking the rules for the operation queues. Is it possible that after you pass it on to the queue, the queue should take responsibility, and therefore you should not manually release it? (Not sure if you are or not).

From my personal experience, and maybe this will help or not:

1) When you cancel op, remove the KVO watchers from it. It turned out that KVO does not get disconnects when both sides are removed.

2) Keep in mind that KVO callbacks are executed in the same thread as NSOperation. Thus, it is possible that the object goes out of scope between the start time of the operation and the KVO callback.

I could help you if you submit the code. Hope this was helpful to you!

+1
source share

All Articles