父 NSManagedObjectContext 必须使用 NSPrivateQueueConcurrencyType 或 NSMainQueueConcurrencyType

Posted

技术标签:

【中文标题】父 NSManagedObjectContext 必须使用 NSPrivateQueueConcurrencyType 或 NSMainQueueConcurrencyType【英文标题】:Parent NSManagedObjectContext must use either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType 【发布时间】:2019-10-29 15:16:32 【问题描述】:

在 macOS 应用程序上,我有一个简单的AddEditViewController,它从主视图控制器接收 NSManagedObject。 然后,我创建一个子 NSManagedObjectContext,以便在用户按下取消按钮时轻松恢复更改。

这里是ViewWillAppear()的实现

    super.viewWillAppear()
    // Create child MOC
    self.managedObjectContext = NSManagedObjectContext(concurrencyType: self.parentManagedObjectContext.concurrencyType)
    self.managedObjectContext.parent = self.parentManagedObjectContext

但这给了我以下错误:

[General] Parent NSManagedObjectContext must use either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType.
    0   CoreFoundation                      0x00007fff379aad63 __exceptionPreprocess + 250
    1   libobjc.A.dylib                     0x00007fff6d899bd4 objc_exception_throw + 48
    2   CoreData                            0x00007fff3743676e -[NSManagedObjectContext setParentContext:] + 334
    3   Zacc                                0x00000001000714fa $s4MyApp28AddEditViewControllerC14viewWillAppearyyF + 666

对这里的问题有任何想法吗?我在网上找不到任何东西。

我在 macOS 10.15 上使用 Xcode 11。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

事实证明,问题在于默认情况下,父 MOC 是在 NSPersistentDocument 中使用已弃用的 init() 创建的。此 MOC 作为 concurrencyType: .confinementConcurrencyType 接收,它也已被弃用。 这就是我收到错误的原因。

我通过修改 NSPersistentDocument 中的主 ManagedObjectContext 解决了这个问题:

class Document: NSPersistentDocument 

    override init() 
        super.init()
        // Add your subclass-specific initialization here.
        // Replace moc created with init() (deprecated) with a good one
        let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        moc.mergePolicy = self.managedObjectContext!.mergePolicy
        moc.persistentStoreCoordinator = self.managedObjectContext!.persistentStoreCoordinator
        self.managedObjectContext = moc
    

现在我可以轻松地基于这个好的父 MOC 创建一个子 MOC。

【讨论】:

以上是关于父 NSManagedObjectContext 必须使用 NSPrivateQueueConcurrencyType 或 NSMainQueueConcurrencyType的主要内容,如果未能解决你的问题,请参考以下文章

保存父 NSManagedObjectContext 时出错

父 NSManagedObjectContext 必须使用 NSPrivateQueueConcurrencyType 或 NSMainQueueConcurrencyType

在子 NSManagedObjectContext 中创建与父实体有关系的实体

父 NSManagedObjectContext 在子保存后没有变化,但仅在发布模式下(在调试模式下工作)

取消 NSManagedObjectContext performBlock

子父上下文保存冲突