处理块,完成处理程序,dispatch_async与dispatch_sync

时间:2012-03-01 03:29:24

标签: iphone objective-c xcode

我正在线程中执行数据的在线提取,我想在块执行后立即执行某些操作。

这是我的代码:

- (IBAction)refresh:(UIBarButtonItem *)sender {
    NSLog(@"checking");
    [self editToolbar];
    dispatch_queue_t fetchQ = dispatch_queue_create("Refreshing", NULL);
    dispatch_async(fetchQ, ^{
        [self setupFetchedResultsController];
        [self fetchImonggoItemsDataIntoDocument: self.itemDatabase];
    });
    dispatch_release(fetchQ); 

    NSLog(@"done checking");
    //do something here
}

事情是dispatch_async立即返回,“完成检查”甚至在块执行完毕之前立即打印。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

我认为这是一个架构问题。任务类似于:

  1. 编辑工具栏
  2. fetchImonggoItemsDataIntoDocument
  3. 做其他事
  4. 如果这些必须完全按顺序完成,那么我就不太了解块或队列的使用;只需在彼此之后运行语句就可以了。

    否则,备选方案#1将使用dispatch_sync而不是dispatch_async。同样,我不太确定使用队列的好处是什么,但它确实存在。

    备选方案#2将使用来自块的回调。类似的东西:

    - (IBAction)refresh:(UIBarButtonItem *)sender {
        NSLog(@"checking");
        [self editToolbar];
        dispatch_queue_t fetchQ = dispatch_queue_create("Refreshing", NULL);
        dispatch_async(fetchQ, ^{
            [self setupFetchedResultsController];
            [self fetchImonggoItemsDataIntoDocument: self.itemDatabase];
            [self doneChecking]; // <-- NOTE! call the callback
        });
        dispatch_release(fetchQ); 
    }
    
    // NOTE! refresh: has been split up into two methods
    - (void)doneChecking:
        NSLog(@"done checking");
        //do something here
    }
    

答案 1 :(得分:1)

正如其他人已经建议的那样,这可能就是你所需要的。

NSArray *items = [iMonggoFetcher fetchImonggoData:IMONGGO_GENERIC_URL_FOR_PRODUCTS withFormat:@"json" withDateRangeArgs:args];
[document.managedObjectContext performBlock:^{
    for (NSDictionary *itemInfo in items){
        [Product productWithImonggoInfo:itemInfo inManagedObjectContext:document.managedObjectContext];
    }
    // Put here what you need :)
}];