NSPersistentDocument register change for autosave.

The default NSManagedObjectContext vended by NSPersistentDocument has a legacy concurrency type of Thread Confinement which makes it useless for modern Child->Parent patterns.


I supply my own context out of the document with the desired concurrency type of Main Queue. The problem with this is that the standard NSDocument autosave-in-place behaviour is broken by using this context, as the hasChanges flag on my context doesnt trigger the change update.


I have worked around this by listening to NSManagedObjectContextObjectsDidChangeNotification on the custom context.


@interface DDPersistentDocument: NSPersistentDocument
@end

@implementation DDPersistentDocument

-(NSManagedObjectContext *)mainThreadContext
{
    if (!self.viewContext){
        self.viewContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        NSPersistentStoreCoordinator *psc = [[super managedObjectContext] persistentStoreCoordinator];
        self.viewContext.persistentStoreCoordinator = psc;
        self.undoManager = self.viewContext.undoManager;
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notifyChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.viewContext];
    }
    return self.viewContext;
}

- (void)notifyChange:(id)note {
    [self updateChangeCount:NSChangeDone];
}

@end


Is there a way of binding my custom context to the change registry rather than this inelegant "everything is a change" philosophy?

Replies

  • override init()
  • call super.init()
  • Replace the ManagedObjectContext created by your own:
self.managedObjectContext = yourMoc

Access the document's context as usual, and you will get your notifications