如何使用来自备用线程的更改来更新其他上下文

Posted

技术标签:

【中文标题】如何使用来自备用线程的更改来更新其他上下文【英文标题】:how to update other contexts with changes from alternate threads 【发布时间】:2011-12-14 18:19:07 【问题描述】:

我有一个在主线程上使用的 mainContext。创建 mainContext 后,我​​将观察者添加到 NotificationCenter 以获取 NSManagedObjectContextDidSaveNotification 通知。

如果创建了一个新线程并且需要一个 NSManagedObjectContext,我会在新线程上创建上下文并为其存储一些信息。我在新线程上保存对上下文的更改。

我的通知处理程序被调用并合并其线程上所有上下文的更改。我对每个受影响的上下文都有一个合并策略,并且我正在合并适当线程上的更改。

我仍然随机得到“乐观锁定失败”。有什么我遗漏的吗?

- (void)contextChanged:(NSNotification *)notif


    //gets called from the thread(where the context was) that made the changes
    //iterate over all contexts and mergeChanges on their thread
    NSLog(@"NotifContext %@ %p", [notif object], [NSThread currentThread]);

    //always check the main
    if([notif object] != [self mainContext])
        NSLog(@"merge with main %@", [self mainContext]);
        [[self mainContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notif waitUntilDone:NO];
    


    //check alternate cotexts and merge changes on their threads
    NSDictionary *altContexts = [self.altContexts copy];
    for(NSString *threadAddress in altContexts)
        NSDictionary *info = [altContexts objectForKey:threadAddress];
        NSManagedObjectContext *context = [info objectForKey:@"context"];
        if(context != NULL && [notif object] != context)
            NSLog(@"merge with %@", context);
            NSThread *thread = [info objectForKey:@"thread"];
            [context performSelector:@selector(mergeChangesFromContextDidSaveNotification:) onThread:thread withObject:notif waitUntilDone:NO];
        else
            NSLog(@"not with %@", context);
        
    
    [altContexts release];

【问题讨论】:

【参考方案1】:
waitUntilDone:NO //should have been YES

我忽略了这一点。我的意思是等它完成。否则,保存发生(在线程 2 上),通知被调度, contextChanged: 处理程序被触发,其他上下文被告知合并其线程上的更改(例如线程 1),线程 2 在线程 1 上的上下文之前继续实际上可以保存。

【讨论】:

以上是关于如何使用来自备用线程的更改来更新其他上下文的主要内容,如果未能解决你的问题,请参考以下文章

更改上下文时如何立即更新错误值

如何使用 ReadDirectoryChangesW 区分 ADS(备用数据流)与主流更改

并发编程中,如何减少上下文切换

使用 OpenGL 和来自不同线程的输入

如何修复“当前线程与渲染器的同步上下文无关”?

iOS 在后台保存主线程 NSManagedObjectContext 更改