Recommended design patterns for asynchronous blocks?

I am working on an asynchronous design iOS application. There are situations when one conceptual โ€œoperationโ€ can queue many child blocks that will execute asynchronously and receive their responses (calls to the remote server) asynchronously. Any of these child blocks may complete execution in an error state. If an error occurs in any child block, any other child blocks must be canceled, the error state must be percolated to the parent, and an error handling block must be executed.

I wonder what design patterns and other tips might be recommended for working in such an environment?

I know the capabilities of GCD dispatch_group_async and dispatch_group_wait. This may be a flaw in this application design, but I was not lucky with dispatch_group_async because the group does not seem to be sticky for child blocks.

Thanks in advance!

+6
source share
3 answers

There is a video of WWDC (2012) that is likely to help you. It uses a custom NSOperationQueue and places asynchronous blocks inside NSOperations so that you can hold the block descriptor and cancel the remaining queues.

The idea would be for error handling of child blocks to call a method in the main thread in the class that processes NSOperationQueue . Then the class can undo the rest. Thus, the child block needs to know only its thread and the main thread. Here is the link to the video

https://developer.apple.com/videos/wwdc/2012/

The video is called Creating Parallel User Interfaces on iOS. The relevant part is mainly in the second half, but you probably want to see all this, as it fits perfectly into the context.

EDIT:

If possible, I would recommend processing the response in a built-in block that perfectly combines it, which I think you need.

 //Define an NSBlockOperation, and get weak reference to it NSBlockOperation *blockOp = [[NSBlockOperation alloc]init]; __weak NSBlockOperation *weakBlockOp = blockOp; //Define the block and add to the NSOperationQueue, when the view controller is popped //we can call -[NSOperationQueue cancelAllOperations] which will cancel all pending threaded ops [blockOp addExecutionBlock: ^{ //Once a block is executing, will need to put manual checks to see if cancel flag has been set otherwise //the operation will not be cancelled. The check is rather pointless in this example, but if the //block contained multiple lines of long running code it would make sense to do this at safe points if (![weakBlockOp isCancelled]) { //substitute code in here, possibly use *synchronous* NSURLConnection to get //what you need. This code will block the thread until the server response //completes. Hence not executing the following block and keeping it on the //queue. __block NSData *temp; response = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]; [operationQueue addOperationWithBlock:^{ if (error) { dispatch_async(dispatch_get_main_queue(), ^{ //Call selector on main thread to handle canceling //Main thread can then use handle on NSOperationQueue //to cancel the rest of the blocks }); else { //Continue executing relevant code.... } }]; } }]; [operationQueue addOperation:blockOp]; 
+5
source

One pattern I came across after posting this question was using a semaphore that would change the asynchronous operation in a synchronous operation. It was very helpful. This blog post describes this concept in more detail.

http://www.g8production.com/post/76942348764/wait-for-blocks-execution-using-a-dispatch-semaphore

+1
source

There are many ways to achieve asynchronous behavior in cocoa.

GCD, NSOperationQueue, performs a SelectorAfterDelay, creating its own threads. There are appropriate times for using these mechanisms. Too long to discuss here, but what you mentioned in your post needs a solution.

If an error occurs in any child block, any other child blocks must be canceled, the error state must be skipped to the parent, and the parent error handling block must be executed.

Blocks errors with an error in the stack. Period.

-1
source

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


All Articles