核心数据和多线程(和绑定使其更有趣)

时间:2011-06-10 13:41:47

标签: multithreading core-data binding

我有这个后台线程,它对核心数据对象做了一些事情。我得到如下背景:

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

然后我获取一些对象,修改它们并保存上下文:

- (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]; 
}

..后来我删除了观察者。这适用于主要部分。但是当一些属性合并回来时,它们不会得到更新。在更新之前为零的属性。有价值的那些保持不变。

我试过了:

[newContext setMergePolicy:NSOverwriteMergePolicy];
主要上下文中的

...(以及其他合并策略)但它不起作用:P

感谢您的帮助。

注意:我已将值绑定到NSTableView。我在合并后记录它们。零值的属性似乎工作正常。

1 个答案:

答案 0 :(得分:5)

您如何注册通知的两个上下文?你需要做这样的事情:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

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

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

实现回调:

// 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];
    }
}