CoreData堆栈[子(背景)/父(线程1)]设置mergeChangesFromContextDidSaveNotification不更新UI(tableview)

时间:2013-07-06 03:25:29

标签: ios core-data

快速提问。我有一个核心数据堆栈(子/父)上下文。 孩子取出json objs并解析它们然后将它们保存到父级,当计数为20时,父级获取主线程并保存...一切正常。但是在我的tableview中,我最终每次都要重新获取整个数据库!我的fetchcount和持续时间是巨大的,可以任何人给我一些想法?我全力以赴提前谢谢!也出于某种原因[[[SharedStore ShareStoreManager] getMasterContext] reset]工作正常......只是没有mergeChangesFromContext!

NSNotificationCenter *mergeNotification = [NSNotificationCenter defaultCenter];
[mergeNotification addObserver:self
                      selector:@selector(mergeChanges:) 
                          name:NSManagedObjectContextDidSaveNotification 
                        object:[[SharedStore ShareStoreManager]getMasterContext]]



-(void)mergeChanges:(NSNotification *)notification {
     [[[SharedStore ShareStoreManager]getMasterContext] mergeChangesFromContextDidSaveNotification:notification];
     [self.tableView layoutIfNeeded];
     [self.tableView reloadData];
}  
编辑:我甚至进入上下文对象,看到没有合并的插入项目,所以我进去那里强迫它但仍然没有运气帮助!!!

for (User *user in [[notification.userInfo objectForKey:@"inserted"] allObjects]) {
        [[[SharedStore ShareStoreManager]getMasterContext] refreshObject:user mergeChanges:YES];
    }
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}

1 个答案:

答案 0 :(得分:1)

我会重新考虑您的设计并使用NSFetchedResultsController来获取您的对象。将该类用于数据源的好处在于,当托管对象上下文中的内容发生变化时,它会自动收到通知。通过implementing the delegate回调,您可以让tableview通过在表视图中插入,删除,移动,修改相应的行来响应获取的结果控制器数据中的更改。

Here's a tutorial逐步概述如何将其全部挂起。

修改 查看代码,在添加观察者时,您只是在监听主上下文发生的保存。如果您使用单独的上下文进行后台处理,则此通知仅针对该背景上下文发布,因此不会触发您的观察者。主上下文将触发该通知的唯一方法是将背景上下文与主线程上下文合并并保存主线程上下文。

您的核心数据堆栈类应该有自己的观察者,监听所有保存事件:

[[NSNotificationCenter defaultCenter] addObserver:sharedController
                                         selector:@selector(contextDidSave:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:nil];

然后它应该合并主线程上不同线程和上下文上发生的更改:

- (void)contextDidSave:(NSNotification *)notification {
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self contextDidSave:notification];
        });
    } else {
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
    }
}

请注意,我们确保在主线程上执行合并,因为主要上下文是在主线程上创建的,并且不是线程安全。合并完成后,通知将发送给观察者,例如NSFetchedResultsController,然后将触发自己的委托回调,让您有机会刷新UI。