On Feb 1, 2013, at 6:59 PM, Mike Abdullah <cocoa...@mikeabdullah.net> wrote:

> On 1 Feb 2013, at 20:13, mail...@ericgorr.net 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.

Well, my first problem is that I currently need to support 10.6, but for 
various reasons I may suggest changing that to 10.7.

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

Interesting solution. Yes, blocking the main thread is not an option for me.

I am a bit surprised that such basic functionality is supported directly 
somehow.

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

If I understand this correctly, BSManagedDocument is a complete drop-in 
replacement for NSPersistentDocument?

I will take a closer look at the code.









_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to