主线程上的 NSFetchedResultsController 忽略从不同线程保存到核心数据?
Posted
技术标签:
【中文标题】主线程上的 NSFetchedResultsController 忽略从不同线程保存到核心数据?【英文标题】:NSFetchedResultsController on main thread ignoring saves to Core Data from a different thread? 【发布时间】:2011-12-22 19:02:23 【问题描述】:我在主线程上有一个NSFetchedResultsController
。同样从主线程,我异步发送一个 JSON 网络请求。当该 JSON 字符串返回时,我启动一个 NSOperation
,它初始化一个新的(背景)NSManagedObjectContext
,解析 JSON 字符串,创建/更新 NSManagedObject
,并将它们保存在上下文中。后台上下文与主上下文具有相同的 persistentStore。有了这个,我有两个问题:
我认为从任何上下文(在任何线程上)保存到持久存储区都会通知主 NSFetchedResultsController
有更改,但到目前为止它没有收到任何更改。我应该做些什么来通知主线程的NSFetchedResultsController
有外部save
以便tableView
相应地更新?
所以,在主线程上,我订阅了NSManagedObjectContextWillSaveNotification
,并正确地看到所有上下文(包括完全存在于单独线程上的上下文)何时执行save
操作。 apple docs 说 notification.userInfo
应该有一个包含 3 个数组的字典,一个数组用于后台线程上的每个“更新、删除和插入”模型对象。但是,userInfo
对我来说始终是 nil
。任何想法我做错了什么?
订阅 AppDelegate 中的NSManagedObjectContextWillSaveNotification
:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextWillSaveNotification
object:nil];
以及AppDelegate中保存上下文的方法:
- (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?
我还想知道处理多线程(使用单独的 NSManagedObjectContexts)和核心数据的最佳实践。
【问题讨论】:
【参考方案1】:您观察到错误的通知:您需要观察的通知名称是NSManagedObjectContextDidSaveNotification
(不是NSManagedObjectContextWillSaveNotification
)。
【讨论】:
太棒了! userInfo 现在填充了正确的字典。将这些更改通知NSFetchedResultsController
怎么样?您是否建议我将这些更改合并到主要上下文中,或者是否有更简单的方法来更新NSFetchedResultsController
?
控制器依赖于主上下文,因此正确的方法(实际上是唯一的方法)是将更改合并到该上下文中。
是的,您应该告诉主上下文使用-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:]
合并更改。如果NSFetchedResultController
有委托,它将自动刷新其内容并将更改通知其委托。否则,您可以发送 performFetch:
重新加载内容。以上是关于主线程上的 NSFetchedResultsController 忽略从不同线程保存到核心数据?的主要内容,如果未能解决你的问题,请参考以下文章
在后台创建的 NSManagedObject 变成了主线程上的错误
无法访问主线程上的数据库 - Android Room - 使用 ThreadPoolExecutor
XMLHTTPRequest 错误:不推荐使用主线程上的同步 XMLHttpRequest ...(SoundCloud API)