Re: Core Data & NSPersistentDocument & Concurrency
Re: Core Data & NSPersistentDocument & Concurrency
- Subject: Re: Core Data & NSPersistentDocument & Concurrency
- From: Mike Abdullah <email@hidden>
- Date: Fri, 01 Feb 2013 23:59:44 +0000
On 1 Feb 2013, at 20:13, email@hidden wrote:
> I've got a NSPersistentDocument. I have read the Concurrency with Core Data in the Core Data Programming Guide and am following the typically recommended approach which is to create separate managed object context (MOC) for each thread, but to share a single persistent store coordinator (PSC)
>
> I am using a NSOperation which does create its own MOC and does share the PSC with the main thread. The operation adds some objects and I call [MOC save:&error]. This succeeds and a NSManagedObjectContextDidSaveNotification is generated and I get this on the main thread. I then call the mergeChangesFromContextDidSaveNotification method while handling the notification on the main thread. I can see the objects saved in my document.
>
> The problem then is that my NSPersistentDocument generates an error which says:
>
> "The document "xxx" could not be saved. The file has been changed by another application"
>
> Of course, the other application is the NSOperation which did change the document.
>
> How can I correctly avoid the error?
The problem here is you're modifying the document on disk behind NSDocument's back. This has the immediate consequence of changing the modification date. But it also has subtler ramifications from sidestepping NSFileCoordinator and Versions.
On OS X 10.7, Core Data offers child contexts. You could setup your background contexts to be children of the main one. This way when they save, they would only be saving back into the main context, without touching the store on disk.
One downside of that is whenever a child needs to fetch data, it must do so via the main context, blocking the main thread while doing so. Depending on your model, that may prove unacceptable. If so, your better bet is to have a single "root" context with its own private queue. Make the main context a child of it. And then also make any background contexts children of it.
At that point, you start to leave NSPersistentDocument's remit. I have code here demonstrating how to do subclass NSDocument directly for this setup:
https://github.com/karelia/BSManagedDocument
(make sure you checkout the ksmanageddocument branch!)
One great advantage is it leverages the root context to implement asynchronous saves. Out of the box it is designed to match UIManagedDocument's document package layout, but I'm sure you could adjust that. Or perhaps just re-use bits of the code in your NSPersistentDocument subclass.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden