Waiting for multiple blocks to finish

后端 未结 5 639
被撕碎了的回忆
被撕碎了的回忆 2020-12-28 09:33

I have those methods to retrieve some object information from the internet:

- (void)downloadAppInfo:(void(^)())success
                failure:(void(^)(NSErr         


        
5条回答
  •  轮回少年
    2020-12-28 10:10

    Drawn from the comments in other answers here, and the blog post Using dispatch groups to wait for multiple web services, I arrived at the following answer.

    This solution uses dispatch_group_enter and dispatch_group_leave to determine when each intermediate task is running. When all tasks have finished, the final dispatch_group_notify block is called. You can then call your completion block, knowing that all intermediate tasks have finished.

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    [self yourBlockTaskWithCompletion:^(NSString *blockString) {
    
        // ...
    
        dispatch_group_leave(group);
    }];
    
    dispatch_group_enter(group);
    [self yourBlockTaskWithCompletion:^(NSString *blockString) {
    
        // ...
    
        dispatch_group_leave(group);
    }];
    
    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
    
        // All group blocks have now completed
    
        if (completion) {
            completion();
        }
    });
    

    Grand Central Dispatch - Dispatch Groups

    https://developer.apple.com/documentation/dispatch/dispatchgroup

    Grouping blocks allows for aggregate synchronization. Your application can submit multiple blocks and track when they all complete, even though they might run on different queues. This behavior can be helpful when progress can’t be made until all of the specified tasks are complete.

    Xcode Snippet:

    I find myself using Dispatch Groups enough that I've added the following code as an Xcode Snippet for easy insertion into my code.

    Now I type DISPATCH_SET and the following code is inserted. You then copy and paste an enter/leave for each of your async blocks.

    Objective-C:

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    
    dispatch_group_leave(group);
    
    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
    
    });
    

    Swift:

    let dispatchGroup = DispatchGroup()
    
    dispatchGroup.enter()
    
    dispatchGroup.leave()
    
    dispatchGroup.notify(queue: .global()) {
    
    }
    

提交回复
热议问题