I am using NSOperation to perform some heavy parsing of data, then return back to the main thread with objects ready to be used by my app. I handle all operations by placing them on a singleton NSOperationQueue. I do this to control how much processing is happening at any point, because each operation temporarily uses a pretty high memory footprint.
So, I have a scenario where I can have several view controllers on screen. Each view controller will create a parsing operation on load and add it to the queue. I allow 2 concurrent processing operations by setting the maxConcurrentOperationCount. Each view controller creates a processing operation, places it on the singleton queue, and retains the operation as a property so it has a handle on it.
If the view controller needs to go away in response to a user initiated Delete action, I use the NSOperation property in the dealloc method of my view controller to cancel the operation:
-(void)dealloc{
[self.currentOperation cancel];
[super dealloc];
}
In my NSOperation subclass, I check the isCancelled property in several places (mostly before significant chunks of long running work) the isCancelled property and attempt to respond to it:
if([self isCancelled]){
// Perform cleanup
return;
}
The problem is that the isCancelled property is evaluating to false and the operation continues, eventually calling into Core Data to attempt to retrieve data that has been deleted. I see this happen even when I place an isCancelled check immediately prior to the Core Data fetch request.
I've got a workaround to keep the app from crashing, but I'm thinking I might be going about the implementation wrong. Is there any other way I can maintain a handle on the operation while it is processing so I can cancel it if needed? Is my method not retaining the proper handle on the operation and preventing it from being properly cancelled?