vomi
vomi

Reputation: 1163

Parent NSManagedObjectContext must use either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType

on a macOS application, I have a simple AddEditViewController that receives a NSManagedObject from the main View Controller. I then create a child NSManagedObjectContext to easily revert changes if the user presses the cancel button.

Here is the implementation of ViewWillAppear()

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

But this gives me the following error:

[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

Any idea of the issue here? I could not find anything on the web.

I'm using Xcode 11 on macOS 10.15.

Thanks for the help!

Upvotes: 1

Views: 226

Answers (1)

vomi
vomi

Reputation: 1163

It turns out the issue is that the parent MOC is created by default in the NSPersistentDocument with the deprecated init(). This MOC receives as concurrencyType: .confinementConcurrencyType which is also deprecated. This is why I was getting the error.

I fixed this by modifying the main ManagedObjectContext in NSPersistentDocument:

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
    }
}

Now I can easily create a child MOC based on this good parent MOC.

Upvotes: 1

Related Questions