Is it possible to undo a block added to NSOperationQueue with addOperationWithBlock :?

I have read many articles that say: "BLOCKS - FUTURE !!!". I am wondering if this relates to running operations in the background.

For example, I have a table view in which there are images that will come from the Internet. Right now I can get them to use +[NSOperationQueue addOperationWithBlock:] . The operation is queued when the cell becomes visible. But is there a way to cancel it as soon as the cell scrolls from the screen? Or is this the only way to do this for a subclass of NSOperation ? Using blocks is so simple, so I just ask this question before trying to solve this NSOperation subclass NSOperation ...

+6
source share
4 answers

The question is, is it possible to create a canceled NSBlockOperation . As this answer suggests, citing the WWDC 2012 session # 211, creating parallel user interfaces , you certainly can.

However, this approach consists of limitations. It is noteworthy that you must put the undo logic in your block. This works fine if your block runs some loop in which it can repeatedly check the status of isCancelled . But if you are in the middle of some kind of network request, it will be inconvenient to execute in NSBlockOperation .

Using the template described in this other answer (and in this WWDC 2012 video), you can write NSBlockOperation , which used a tortured combination of NSURLSession -based NSURLSession and a polling cycle that cancels the NSURLSessionTask if the operation is canceled, which does what you intend , but this is a terrible decision (inefficient, cumbersome, burdening your application code with undo logic in a block, etc.).

If you want to do a NSOperation transaction, subclassing NSOperation will be a much more elegant way to do this. The first time you do this, it will seem cumbersome, but as soon as you become familiar with the template, it will become second nature and trivial to implement. And you return again and again to this pattern. See the section Defining a User-Defined Work Object in the Operation Queues section of the Concurrency Programming Guide for discussions on cancellation, simultaneous operations, in particular the discussion “Responding to Cancellation Events”.

As a final note, you describe these “usage blocks” and NSOperation -subclass as an “either / or” clause. Often, however, you actually go beyond two methods by creating a subclass of NSOperation that accepts block parameters that indicate what you want to do when loading is done. See AFNetworking for a great example of how to marry NSOperation blocks and subclass.

+11
source

In the note “Checkout the WWDC 2015”, this is a great example of how you can use NSOperations in your project:

https://developer.apple.com/videos/wwdc/2015/?id=226

About your canceled blocks, you should check ReactiveCocoa . This is an ideal solution for me, as you can cancel the signals of network requests: https://github.com/ReactiveCocoa/ReactiveCocoa

I also used it to create delayed delayed blocks. You can read more about it here: http://www.avanderlee.com/2015/07/25/cancellable-delayed-blocks/

+1
source

Based on @Antoine's idea

- (void(^)())executeSomeBlock:(void(^)())someBlock { __block volatile int32_t isCancelled = 0; [self.someOperationQueue addOperationWithBlock:^(){ if (!isCancelled) { someBlock(); } }]; return ^(){OSAtomicCompareAndSwap32Barrier(0, 1, &isCancelled);}; }

Using:

void (^cancelMe)() = [self executeSomeBlock:myBlock];

If you want to cancel the block:

cancelMe();

Never check it out. Feel free to try.

I suggest that this idea can be turned into the NSOperation category.

*** Updated by @CouchDeveloper

0
source

You can do it this way

 NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; //... NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ }]; [opQueue addOperation:operation]; //... [operation cancel]; 
-3
source

Source: https://habr.com/ru/post/970473/


All Articles