4

我注意到可以NSManagedObjectContext使用NSMainQueueConcurrencyTypeto performBlockAndWait: 并在接收者的(主)队列以外的队列上执行块。

例如,如果 my是 type并且 my是 type ,则以下代码将导致我parentContext执行childContext's 队列上的块:parentContextNSMainQueueConcurrencyTypechildContextNSPrivateQueueConcurrencyType

[childContext performBlockAndWait:^{
    //Thread 1, Queue: NSManagedObjectContext Queue
    [parentContext performBlockAndWait:^{
        //Thread 1, Queue: NSManagedObjectContext Queue
        //This is the same queue as the child context's queue
    }];
}];

相反,以下代码按预期工作——我parentContext在主队列上执行块:

[childContext performBlock:^{
    [parentContext performBlockAndWait:^{
        //Thread 1, Queue: com.apple.main-thread
    }];
}];

这是预期的行为吗?由于文档状态,这肯定让我感到困惑"performBlockAndWait: synchronously performs a given block on the receiver’s queue."

4

1 回答 1

3

您不必担心执行了哪些线程块。performBlock:performBlockAndWait:方法保证的是线程安全。因此,从主线程调用performBlockAndWait:并不意味着会有上下文切换到后台线程 - 它非常昂贵并且不需要。如果在块的操作期间(在主线程上),尝试执行块,它将被阻塞,直到当前正在执行的块完成。在一天结束时,结果将与执行上下文切换相同,只是更快。另一方面,调用performBlock:会将块排队到任意队列中,通常在后台线程上执行。

在上面的示例中,由于 you performBlockAndWait:,您的私有队列上下文在主线程上执行您的块,主上下文块也是如此。在您的第二个示例中,您安排块异步运行,因此它在后台线程上执行。

你不应该通过它的名字来判断一个线程的队列。要查看您是否在主队列中,您可以使用dispatch_get_current_queue()并测试它是否等于dispatch_get_main_queue().

于 2013-10-18T00:53:50.137 回答