MKNetworkKit and GCD dispatch_group_t

不羁的心 提交于 2019-12-24 19:46:30

问题


I am trying to use MKNetworkKit to fetch an array of links from a web service, then parse each response on a background thread, and use the dispatch_group_t of GCD to wait until all threads are finished processing. Where I'm stuck is I can't figure out why my dispatch_group_notify is not waiting for all threads in the group to complete. Running this code will print:

results count: 0
added into results, count: 1
added into results, count: 2

The dispatch group is not waiting on its threads. I have also tried dispatch_group_wait but that gave me a crash. I don't know if MKNetworkKit's use of NSOperation is conflicting with this issue. Thanks for any help!

- (MKNetworkOperation *)getABunchOfMovies:(NSArray *)movies onCompletion:(CastResponseBlock)completionBlock onError:(MKNKErrorBlock)errorBlock
{
    MKNetworkOperation *operation;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    block NSMutableArray *results = [[NSMutableArray alloc] initWithCapacity:[movies count]];

    for (NSString *movieTitle in movies) {
        operation = [self operationWithPath:REQUEST_URL(API_KEY, [movieTitle urlEncodedString])];

        [operation onCompletion:^(MKNetworkOperation *completedOperation) {

            dispatch_group_async(group, queue, ^{
                NSDictionary *response = [completedOperation responseJSON];
                id result = [self processResponse:response withMovieTitle:movieTitle];

                @synchronized (results) {
                    [results addObject:result];
                    NSLog(@"added into results, count: %d", [results count]);
                }
            });
        }
                        onError:^(NSError *error) {
                            errorBlock(error);
                        }];

        [self enqueueOperation:operation];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"results count: %d", [results count]);

        // Return array here
        completionBlock(results);
    });

    dispatch_release(group);

    return operation;
}

Edit: I still can't figure out why, but if I change it to use dispatch_group_enter(group); and match it with a dispatch_group_leave(group); at the end of the completion block, it works. Does anyone have any idea why this is happening?


回答1:


At the moment MKNetworkKit doesn't support queue completion handlers. You should consider adding operation dependency instead of this hack.

[lastOperation addDependency:op1];
[lastOperation addDependency:op2];

and assume that when "lastOperation" completes, the queue has indeed completed.

Another way is to KVO the "operationCount" keypath on the engine and check if it reaches zero.

MKNetworkEngine has a code block that does this to show and hide the network activity indicator.



来源:https://stackoverflow.com/questions/11858527/mknetworkkit-and-gcd-dispatch-group-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!