2014-05-15 63 views
1

我已经看到dispatch_async调用dispatch_async与dispatch_async调用dispatch_sync的常见习语。dispatch_async调用dispatch_async vs dispatch_async调用dispatch_sync

在某些情况下,后者可以用前者代替。问题是,在什么情况下你只能使用一个而不使用另一个?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // 
    }); 
}); 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // 
    }); 
}); 

回答

1

第二个选项才有意义,如果你有dispatch_async内的其他代码,你想里面dispatch_sync完成的代码之后执行的代码。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    // A) Some code here 

    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // B) some code here 
    }); 

    // C) Some code here 
}); 

这确保A被执行,然后B(在主线程上),然后C(在后台线程上但在B代码完成后)。

如果没有C代码,则使用dispatch_syncdispatch_async作为内部调度结果的结果相同。

+0

如果没有C代码,逻辑效果是一样的,但实际效果是你保持一个线程占用但什么都不做。 –

1

我会说你应该努力避免阻塞线程。如果您试图使用dispatch_sync(),因为在您正在对主线程分流的内容完成后要运行代码,则应该使用“延续传递”编码风格。您提交给主队列的任务应将新任务提交到并发队列。因此,代码可能看起来像:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    // A) Some code here 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // B) some code here 

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      // C) Some code here 
     }); 
    }); 
}); 

使用dispatch_sync()的主要原因是,当你实现一个固有的同步接口,但你需要派遣任务队列来实现这一目标。这通常只发生在使用串行调度队列(或并发队列上的屏障任务)来保护共享资源时。

鉴于原始代码已经有一个dispatch_async()调用,它不能实现同步接口。