Zigglzworth
Zigglzworth

Reputation: 6823

Performing block operations on objects in array and completing when all complete

I have an array of objects on which I would like to perform block operations. I am not sure the best way to do this. I am doing something like in the code below but I don't think this is the best practice. What is the best way to do such an operation?

- (void)performBlockOnAllObjects:(NSArray*)objects completion:(void(^)(BOOL success))completionHandler {
    NSInteger counter = objects.count;
    for (MyObject *obj in objects) {
        [obj performTaskWithCompletion:^(NSError *error) {
            counter--;
            if (counter == 0) {
                completionHandler(YES);
            }
        }];    
    }
}

Upvotes: 4

Views: 99

Answers (1)

Rob
Rob

Reputation: 438287

Typically you'd use dispatch groups for this. You "enter" the group before you call your method, you "leave" in the completion handler, and then specify a block that should be called when the group notifies you that all "enter" calls have been offset with "leave" calls.

- (void)performBlockOnAllObjects:(NSArray*)objects completion:(void(^)(BOOL success))completionHandler {

    dispatch_group_t group = dispatch_group_create();

    for (MyObject *obj in objects) {
        dispatch_group_enter(group);
        [obj performTaskWithCompletion:^(NSError *error) {
            dispatch_group_leave(group);
        }];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        completionHandler(YES);
    });
}

This is the typical pattern for specifying a block of code to be called asynchronously when a series of other asynchronous tasks complete.

Upvotes: 6

Related Questions