【问题标题】:NSPrivateQueueConcurrencyType serial or concurrent?NSPrivateQueueConcurrencyType 串行还是并发?
【发布时间】:2017-06-01 18:37:57
【问题描述】:

正如标题所说,问题是,并发类型为NSPrivateQueueConcurrencyTypeNSManagedObjectContext 是串行的还是并发的。

更具体地说,如果我打电话给

[managedObjectContext performBlock:^{

}];

对于一个长时间运行的任务,是否会阻止其他使用 performBlock 对该上下文的调用,直到第一个调用完成?

【问题讨论】:

    标签: objective-c core-data


    【解决方案1】:

    是来自Apple docs的串行队列。

    或者您可以简单地尝试运行此代码并查看结果。编号将连续打印。

        let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
        privateMOC.perform {
            for i in 0...8000 {
                if i.isMultiple(of: 3000) {
                    print("1")
                }
            }
        }
        privateMOC.perform {
            for i in 0...8000 {
                if i.isMultiple(of: 3000) {
                    print("2")
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      我认为这两种方式都没有记录。然而,Core Data 通常不是线程安全的,performBlockperformBlockAndWait 方法是处理这种情况的方法——将所有 Core Data 工作放在一个队列中。因此,如果它是一个并发队列,我会感到非常惊讶,因为重点是避免并发。

      【讨论】:

        【解决方案3】:

        我在官方文档中找不到任何证据,但最近我与NSPrivateQueueConcurrencyType 合作,我记得它是连续的。 this blog post 还声明:

        当使用初始化器 initWithConcurrencyType:NSPrivateQueueConcurrencyType] 或 -[initWithConcurrencyType:NSMainQueueConcurrencyType] 创建 NSManagedObjectContext 时,所有对上下文的访问及其托管对象都必须通过方法 -[performBlock: 或 -[performBlockAndWait:] 。 Core Data 使用串行队列来确保对上下文的操作按顺序执行,并且一次只发生一个操作

        【讨论】:

          【解决方案4】:

          这是一个串行队列。当您调用performBlockperformBlockAndWait 如果您指定NSPrivateQueueConcurrencyType 时,您的代码将连续执行。

          Apple 不会在 Apple 的文档中随机选择 PrivateQueue 一词,Private Queue = Serial Queue。看到这里Serial Queue description

          串行队列(也称为私有调度队列)按添加到队列的顺序一次执行一项任务。

          另外,我在调试中仔细检查了这一点。请参阅以下屏幕截图中的最后一个线程:

          【讨论】:

            【解决方案5】:

            NSMainQueueConcurrencyType 使用主队列。主队列绑定到主线程,因此是串行的。

            主调度队列是一个全局可用的串行队列,它在应用程序的主线程上执行任务。

            【讨论】:

              【解决方案6】:

              我已经测试过所有任务都会按顺序执行,但它可能在不同的线程中执行

               backgroundContext.perform {
                  print("perform------:\(self.number)", Thread.current)
                  self.number += 1
               }
              

              【讨论】:

                猜你喜欢
                • 2018-05-15
                • 1970-01-01
                • 1970-01-01
                • 2019-12-16
                • 2021-05-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-15
                相关资源
                最近更新 更多