如何防止dispatch_group卡住?

Boo*_*oon 8 multithreading objective-c grand-central-dispatch

如何防止dispatch_group卡住?我发现如果没有加载我尝试加载的图像之一(例如由于坏URL),可能会卡在以下代码中(有或没有dispatch_group_wait调用).dispatch_group_notify中的块永远不会被调用.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();

for (...) {
        if (...) {
            dispatch_group_enter(group);
            dispatch_async(queue, ^{

               [self loadImageWithUrl:url onCompletion:^{
                     dispatch_group_leave(group);
               }];
            });
        }
    }

    dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)));
    dispatch_group_notify(group, queue, ^{
        NSLog(@"load image complete");
    });
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 9

dispatch_group_notify组完成后对其块进行排队.你的小组永远不会完成 所以不要使用dispatch_group_notify.只需使用dispatch_group_wait等待超时,然后调度您的块:

    ...    
    dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)));
    dispatch_async(queue, ^{
        NSLog(@"load image complete");
    });
Run Code Online (Sandbox Code Playgroud)

如果你想模仿a dispatch_group_notify超时,只需在自己的异步块中执行上述操作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)));
  dispatch_sync(queue, ^{
      NSLog(@"load image complete");
  });
});
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用返回值dispatch_group_wait来确定是否已完成所有操作,或者是否超时(如果这对您有用).

请记住,之前的块不会被取消,因此它们最终可能会运行完成块.如果这是一个问题,您可能需要向系统添加取消逻辑.