Multithreading 主线程上的NSFetchedResultsController是否忽略从其他线程保存到核心数据?
我在主线程上有一个Multithreading 主线程上的NSFetchedResultsController是否忽略从其他线程保存到核心数据?,multithreading,core-data,nsfetchedresultscontroller,nsmanagedobjectcontext,nsoperationqueue,Multithreading,Core Data,Nsfetchedresultscontroller,Nsmanagedobjectcontext,Nsoperationqueue,我在主线程上有一个NSFetchedResultsController。同样从主线程,我异步发送一个JSON的网络请求。当该JSON字符串返回时,我启动一个NSOperation,该操作初始化一个新的(后台)NSManagedObjectContext,解析JSON字符串,创建/更新NSManagedObject,并将它们保存在上下文中。背景上下文与主上下文具有相同的persistentStore。关于这一点,我有两个问题: 我认为从任何上下文(在任何线程上)保存到持久性存储的任何内容都会通知主
NSFetchedResultsController
。同样从主线程,我异步发送一个JSON的网络请求。当该JSON字符串返回时,我启动一个NSOperation
,该操作初始化一个新的(后台)NSManagedObjectContext
,解析JSON字符串,创建/更新NSManagedObject
,并将它们保存在上下文中。背景上下文与主上下文具有相同的persistentStore。关于这一点,我有两个问题:
nsfetchedresultscoontroller
有更改,但到目前为止,它没有收到任何更改。我是否应该做些什么来通知主线程的NSFetchedResultsController
存在外部save
,以便tableView
相应地更新NSManagedObjectContextWillSaveNotification
,并正确查看所有上下文(包括完全存在于单独线程上的上下文)何时执行保存操作。他们说,notification.userInfo
应该有一个包含3个数组的字典,一个数组用于后台线程上的“更新、删除和插入”模型对象。但是,对我来说,userInfo
总是nil
。知道我做错了什么吗
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
- (void)managedObjectContextDidSave:(NSNotification *)notification {
DLog(@"notification: %@", notification); //not nil
DLog(@"notification user info: %@", notification.userInfo); // always nil... why??
NSManagedObjectContext *theContext = notification.object;
if(theContext != context) {
DLog(@"---- SAVED ON ANOTHER CONTEXT");
// should I notify NSFetchedResultsController that there were context saves on background threads?
// how can I merge contexts if userInfo is nil?
}
}
以及在AppDelegate中保存上下文的方法:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
- (void)managedObjectContextDidSave:(NSNotification *)notification {
DLog(@"notification: %@", notification); //not nil
DLog(@"notification user info: %@", notification.userInfo); // always nil... why??
NSManagedObjectContext *theContext = notification.object;
if(theContext != context) {
DLog(@"---- SAVED ON ANOTHER CONTEXT");
// should I notify NSFetchedResultsController that there were context saves on background threads?
// how can I merge contexts if userInfo is nil?
}
}
我还想知道处理多线程(使用单独的NSManagedObjectContext)和核心数据的最佳做法。您观察到了错误的通知:您需要观察的通知名称是NSManagedObjectContextDidSaveNotification
(而不是NSManagedObjectContextWillSaveNotification
).太好了!userInfo现在已填充了正确的词典。将更改通知NSFetchedResultsController
怎么样?您建议我将这些更改合并到主上下文中,还是有更简单的方法更新NSFetchedResultsController
?控制器依赖于主上下文,因此正确的方法(实际上是唯一的方法)要做到这一点,需要将更改合并到该上下文中。是的,您应该告诉主上下文使用-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:
合并更改。如果NSFetchedResultController
具有委托,它将自动刷新其内容并通知对其委托所做的更改。否则,您可以通过发送performFetch:
重新加载内容。