开发者

Core Data and multithreading (and Bindings to make it more fun)

I have got this background thread that does a few things with core data objects. I get the context as follows:

- (id)_managedObjectContextForThread;
{    
    NSManagedObjectContext * newContext = [[[NSThread currentThread] threadDictionary] valueForKey:@"managedObjectContext"];
    if(newContext) return newContext;

    newContext = [[NSManagedObjectContext alloc] init];
    [newContext setPersistentStoreCoordinator:[[[NSApplication sharedApplication] delegate] persistentStoreCoordinator]];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(_mergeChangesFromManagedObjectContext:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:newContext];

    [[[NSThread currentThread] threadDictionary] setValue:newContext forKey:@"managedObjectContext"];
    return newContext;
}

then I fetch some objects, modify them and save the context:

- (void) saveContext:(NSManagedObjectContext*)context {
    NSError *error = nil;
    if (![context save:&error]) {
        [[NSApplication sharedApplication] presentError:error];
    }
}

- (void)_mergeChangesFromManagedObjectContext:(NSNotification*)notification;
{
    [[[[NSApplication sharedApplication] delegate] managedObjectContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                                                                    withObject:notification
                                                                                 waitUntilDone:YES]; 
}

.. later I remove the observer. This works for the main part. But some properties don't get updated when they get merged back. The properties that were nil before get updated. The ones that had a value stay the same.

I tried:

[newContext setMergePolicy:NSOverwriteMergePolicy];

... (and the other merge policies) on the main context but it did not work :P

Thank you for your help.

Note: I have bound the values t开发者_如何学JAVAo a NSTableView. I log them after the merge. The values properties that were nil seem to work fine.


How are you registering both contexts for notifications? You need to do something like this:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

[nc addObserver:self
       selector:@selector(backgroundContextDidSave:)
           name:NSManagedObjectContextDidSaveNotification
         object:backgroundMOC];

[nc addObserver:self
       selector:@selector(mainContextDidSave:)
           name:NSManagedObjectContextDidSaveNotification
         object:mainMOC];

And implement the callbacks:

// merge changes in background thread if main context changes
- (void)mainContextDidSave:(NSNotification *)notification
{
    SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
    [backgroundMOC performSelector:selector onThread:background_thread withObject:notification waitUntilDone:NO];
}


// merge changes in main thread if background context changes
- (void)backgroundContextDidSave:(NSNotification *)notification
{
    if ([NSThread isMainThread]) {
       [mainMOC mergeChangesFromContextDidSaveNotification:notification];
    }
    else {
        [self performSelectorOnMainThread:@selector(backgroundContextDidSave:) withObject:notification waitUntilDone:NO];
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜