在串行执行其他异步任务后执行异步任务

时间:2016-05-16 11:43:45

标签: ios objective-c multithreading grand-central-dispatch nsoperationqueue

我的内容包含主文件和其他文件。

所以这就是问题所在:首先我需要下载,解压缩并插入数据库中的其他文件,然后才对主文件执行相同的操作。其他文件需要串行下载,主文件必须在它们之后下载。

这样做的正确方法是什么?

现在我这样做:

- (void)checkIfPlacesAreDownloaded:(NSArray *)places{

    [SVProgressHUD showWithStatus:@"Downloading places"];

    dispatch_group_t group = dispatch_group_create();

    for(NSDictionary *place in places){

            BOOL result = [IDGDatabaseManager checkIfPlaceIsDownloaded:place];

            if(!result){
                dispatch_group_enter(group);
                [self downloadPlace:place withCompletionHandler:^{
                    [IDGDatabaseManager setPlaceDownloaded:[place objectForKey:@"place_ID"]
                                       WithCompletionBlock:^(BOOL success, NSError *error) {
                                           dispatch_group_leave(group);
                                       }];
                }];

            }
    }

    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self downloadExcursionWithParams:self.excursionDownloadResponse];
    });


}

只有在" place"中有一个文件时它才有效。阵列。如果有多个文件,则会开始并行下载,但不适合我。

1 个答案:

答案 0 :(得分:1)

我认为downloadPlace:withCompletionHandler:方法在后台并发队列上异步工作。这就是文件下载并行运行的原因。我会使用私有串行队列,或者只是执行下一个:

[SVProgressHUD showWithStatus:@"Downloading places"];

dispatch_group_t group = dispatch_group_create();

// create a serial background queue to run the file downloads
dispatch_queue_attr_t qosAttribute = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
dispatch_queue_t myQueue = dispatch_queue_create("com.YourApp.YourQueue", qosAttribute);

for(NSDictionary *place in places){

    BOOL result = [IDGDatabaseManager checkIfPlaceIsDownloaded:place];

    if(!result){
        dispatch_group_enter(group);

        // run the download async on the serial bg queue
        __weak __typeof(self) weakSelf = self;
        dispatch_async(myQueue, ^{
            __typeof(self) strongSelf = self;

            // we need a semaphore to wait for the download completion
            dispatch_semaphore_t sema = dispatch_semaphore_create(0);
            [strongSelf downloadPlace:place withCompletionHandler:^{
                [IDGDatabaseManager setPlaceDownloaded:[place objectForKey:@"place_ID"]
                                   WithCompletionBlock:^(BOOL success, NSError *error) {
                                       dispatch_semaphore_signal(sema);
                                   }];
            }];
            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
            dispatch_group_leave(group);
        });
    }
}

dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    [self downloadExcursionWithParams:self.excursionDownloadResponse];
});