假設現在有一些task需要去執行,在method裡面我們想等所有task完成再call completionBlock,那麼可以分兩種情況
1. task是synchronous的
2. task是asynchronous的
1比較好解決,用NSOperationQueue加dependency就OK了,2的話需要用到dispatch_group_t group。
範例:AVAssetExportSession的exportAsynchronouslyWithCompletionHandler方法是用來把iPod Library中的音樂轉成檔案用的。
- (void)exportAsynchronouslyWithCompletionHandler:(void (^)(void))handler;
現在我們選擇了一批歌曲轉出,想要在全部歌曲轉完之後收到通知並呈現UI,但是AVAssetExportSession不提供一次轉多個歌曲,我們只能知道個別task完成的時間,但是不知道哪時候全部完成,那麼要如何在全部轉完之後才收到通知呢?
這時候就可以使用dispatch_group_t group等待group裡的task統統完成再執行收尾工作。
- (void) convertMediaItemsToMp3:(MPMediaItemCollection *) collection completionBlock:(void(^)()) block
dispatch_group_t group = dispatch_group_create();
NSArray *songs = collection.items;
for (MPMediaItem *song in songs) {
dispatch_group_enter(group);
AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
initWithAsset:asset
presetName: AVAssetExportPresetAppleM4A];
exporter.outputFileType = @"com.apple.m4a-audio";
exporter.outputURL = ...;
[exporter exportAsynchronouslyWithCompletionHandler:^{
dispatch_group_leave(group);
}];
}
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (block) {
block();
}
});
沒有留言:
張貼留言