2015年1月29日 星期四

Multi async task completion block

假設現在有一些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();
        }
    });

http://stackoverflow.com/a/20910658/1060971

沒有留言:

張貼留言