在NSManagedObjectContext的performBlock中使用dispatch_async

3
根据WWDC 2012视频《Core Data最佳实践》所述,在以NSPrivateQueueConcurrencyType类型创建的上下文中,应使用dispatch_sync来运行某种回调函数。
为什么要这样做呢?
在私有队列的上下文的performBlock中,我能否使用dispatch_async(dispatch_get_main_queue(), 0)来调用一些与UI相关的回调函数?
2个回答

4

不。 NSPrivateQueueConcurrencyType 管理它自己的内部队列,并且不允许您尝试让它的线程去执行您想要执行的操作(事实上,我认为当出现这种行为时,它会抛出异常)。当然有几种处理方法,使用信号量是更可接受的设计模式,可以获得真正的“异步感觉”,但如你所说,dispatch_sync 通常是较好的选择。


实际上我的应用程序在performBlock中使用了dispatch_async,在大多数情况下并没有引起任何问题 :( 这就是为什么我很好奇是否需要使用dispatch_sync。顺便问一句,dispatch_async是否会将控制权移交给其他线程? 我想我最好再学习一下GCD。 - minorblend
如果你指定了一个不同的线程(比如主线程),那么它就会生效。 - CodaFi
那么在 NSPrivateQueueConcurrencyType 的上下文的 performBlock 结束时,调用 dispatch_async(dispatch_get_main_queue()... 是安全的,对吗? - minorblend
3
好的,当然可以。只是performBlock:是一个特定于MOC的方法,而Core Data的黄金规则是“每个线程一个上下文”。 - CodaFi

0

我是通过谷歌来到这里的,如果有人像我一样对这个东西还不熟悉,并且需要一个代码示例,那么这里有一个:

__block dispatch_queue_t currentQ =  dispatch_get_current_queue();

[managedObjectContext performBlock:^{

    //do the stuff you need to do in a background thread

    dispatch_sync(currentQ, ^(){

        //callback code for once the background stuff is complete

    });
}];

上面的代码在语法上是正确的,但我怀疑原因不对。通常,在performBlock:中调用dispatch_sync来更新UI,即告诉视图或viewController数据已更改,需要更新显示。这些调用必须在主线程上进行。您当前的队列可能是主队列,但也可能不是。因此,安全的方法是:__block 'dispatch_queue_t mainQueue = dispatch_get_main_queue();',然后是dispatch_sync(mainQueue,^(){ //update UI }); - Elise van Looij

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接