Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I cancel a Block added to an NSOperationQueue with addOperationWithBlock:?

I've read many many articles which say "BLOCKS ARE THE FUTURE!!!". I'm wondering if it relates to running operations in the background.

For example, I have a table view which has images that will come from the web. Right now I can get them using +[NSOperationQueue addOperationWithBlock:]. An operation gets sent to the queue when the cell becomes visible. But is there a way to cancel it once the cell gets scrolled off the screen? Or is the only way to do it to subclass NSOperation? Using blocks is so easy, so I'm just asking this question before I try to tackle this example of NSOperation subclass...

like image 347
denikov Avatar asked Jun 06 '14 17:06

denikov


1 Answers

The question appears to be whether you can create a cancelable NSBlockOperation. As this answer suggests, quoting from WWDC 2012 session #211, Building Concurrent User Interfaces, you certainly can.

This approach consists of limitations, though. Notably, you have to put the cancellation logic in your block. This works fine if your block is running some loop in which it can repeatedly check the isCancelled status. But if you're in the middle of some network request, this is going to be awkward to perform in a NSBlockOperation.

Using the pattern outlined in that other answer (and that WWDC 2012 video), you could write a NSBlockOperation which employed a tortured combination of block-based NSURLSession and a polling loop which cancels the NSURLSessionTask if the operation is canceled, which accomplishes what you intend, but it's a horrible solution (inefficient, cumbersome, encumbering your app code with cancellation logic in the block, etc.).

If you want to make a cancelable network operation, a NSOperation subclass is going to be a far more elegant way to do this. The first time you do this, it's going to seem cumbersome, but once you familiarize yourself with the pattern, it becomes second nature and trivial to implement. And you'll find yourself coming back to this pattern again and again. See the Defining a Custom Operation Object section of the Operation Queues chapter of the Concurrency Programming Guide for discussions about making cancelable, concurrent operations, notably the discussion about "Responding to Cancellation Events".

As a final observation, you describe this "use blocks" and NSOperation-subclass as an "either/or" proposition. Frequently, though, you actually marry the two techniques, creating an NSOperation subclass that takes block parameters that specify what you want to do when the download is done. See AFNetworking as a wonderful example of how to marry blocks and NSOperation subclass.

like image 145
Rob Avatar answered Sep 28 '22 01:09

Rob