为啥 NSManagedObjectContext 队列在主线程上执行?

Posted

技术标签:

【中文标题】为啥 NSManagedObjectContext 队列在主线程上执行?【英文标题】:why does NSManagedObjectContext Queue execute on main thread?为什么 NSManagedObjectContext 队列在主线程上执行? 【发布时间】:2014-04-08 21:19:03 【问题描述】:

当我向我的 NSPrivateQueueConcurrencyType 类型的 MOC 发送 performBlock 消息时,如下所示:

[self.privateManagedObjectContext performBlockAndWait:^
    if ([[NSThread currentThread] isMainThread]) 
        NSLog(@"executing on the main thread!!");        
    
    …
];

我发现,默认情况下,它在主线程上执行。上述代码中的条件触发,并且问题导航器指示正在执行在NSManagedObject Queue 中的Thread 1

这让我很费解,因为 Apple 告诉我们“每个线程必须有自己的完全私有的托管对象上下文”。假设NSMainQueueConcurrencyType 类型的MOC 将使用主线程,那么NSPrivateQueueConcurrencyType 类型的MOC 使用主线程是否违反了线程限制?

我的代码在主线程上执行是否正常?我误解了线程限制吗?我知道队列不一定与特定线程相关联,但在这种情况下,私有 MOC 队列似乎应该至少避免主线程,如果没有单个转到线程。我有一些奇怪的错误,所以我需要弄清楚发生了什么。谢谢!

【问题讨论】:

【参考方案1】:

这种优化是可能的,因为performBlockAndWait: 执行块 同步,即该方法在块完成之前不会返回。 因此,该块不会与其他操作并行执行 主线程。

(出于同样的原因,dispatch_sync(queue, ...) 可能会在主线程上执行一个块 而不是单独的线程。)

【讨论】:

是的,这篇文章描述的是正确的,但它是否给了这个问题一个答案? @Chengjiong:我想我已经回答了这个问题。您认为缺少什么? 您解释了为什么 performBlockAndWait: 中的块是在主线程中执行的,但是正如我在问题中看到的那样,mkc842 想知道为什么 NSPrivateQueueConcurrencyType 上下文可以在主线程上运行,这是否违反了 Apple 的规则,这些也是我想知道的。 @Chengjiong:NSPrivateQueueConcurrencyType 指定上下文与私有调度queue 相关联。队列未绑定到固定的线程。 GCD 可以在这里选择在主线程上执行非主队列中的块,因为任何其他代码不可能同时在主线程上执行。是减少线程切换次数的优化。 酷,你解开了我的疑惑。我还有一个问题,希望你能帮助我:)。问题是,我在主线程中创建了一个类型为 NSPrivateQueueConcurrencyType 的上下文,来自 Apple 的文档,这是否意味着我只能在主线程中使用由它管理的上下文和 NSManagedObjects?

以上是关于为啥 NSManagedObjectContext 队列在主线程上执行?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在这段代码中得到“未知类型名称 NSManagedObjectContext”?

为啥将 NSManagedObjectContext 保存为“干净”时会出现合并错误?

为啥 NSManagedObjectContext = nil 在第一次尝试获取它之后?

为啥在没有明确合并的情况下,更改可能会从一个 NSManagedObjectContext 填充到另一个?

NSOperation 和 ARC 中 NSManagedObjectContext 保存方法上的 EXC_BAD_ACCESS,为啥?

为啥要保留静态变量?