xcode 处理块、完成处理程序、dispatch_async 与 dispatch_sync
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9510225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dealing with Blocks, completion handlers, dispatch_async vs dispatch_sync
提问by acecapades
I'm executing an online fetch of data in a thread and I want to do something immediately after the block is executed.
我正在线程中执行在线数据获取,并且我想在执行块后立即执行某些操作。
Here's my code:
这是我的代码:
- (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
}
The thing is dispatch_async returns immediately and "done checking" prints immediately even before the block is done executing. How do I solve this?
事情是 dispatch_async 立即返回并且“完成检查”甚至在块执行完成之前立即打印。我该如何解决这个问题?
采纳答案by gregheo
I think it's an architectural issue. The tasks are something like:
我认为这是一个架构问题。任务是这样的:
- edit toolbar
- fetchImonggoItemsDataIntoDocument
- do something else
- 编辑工具栏
- fetchImonggoItemsDataIntoDocument
- 做别的事
If these must be done exactly in order then I don't quite understand the use of blocks or queues; just run the statements after each other and you'll be set.
如果这些必须完全按顺序完成,那么我不太了解块或队列的使用;只需依次运行语句即可。
Otherwise, alternative #1 would be to use dispatch_sync
rather than dispatch_async
. Again, I'm not quite sure what the benefit of using a queue would be but there it is.
否则,替代 #1 将使用dispatch_sync
而不是dispatch_async
. 同样,我不太确定使用队列的好处是什么,但它确实存在。
Alternative #2 would be to use a callback from the block. Something like:
替代方法 #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
}
回答by nacho4d
As others have already suggested, this is probably what you need.
正如其他人已经建议的那样,这可能是您所需要的。
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 :)
}];