我的应用程序首先提供一个tableview,其数据源是Core Data SQLite存储。当应用程序启动时,会创建一个具有自己的商店控制器和上下文的辅助线程,以便从Web获取商店中数据的更新。但是,对存储的任何结果更改都不会通知给fetchedresults控制器(我假设它有自己的协调器),因此表不会随存储更改而更新。刷新主线程上下文的最有效方法是什么?我正在考虑跟踪辅助线程上更改的任何对象的objectID,在辅助线程完成时将它们发送到主线程并调用“[context refreshObject:....]任何帮助都将非常感谢。
答案 0 :(得分:2)
在NSFetchedResultsController
处理该表格时,请在viewDidLoad
或loadView
注册以获取通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:@"ContextDidSave" object:nil];
当辅助线程准备好新数据时,只需像往常一样保存上下文,然后发布通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"ContextDidSave" object:managedObjectContext];
通知将使用以下方法在NSFetchedResultsController
中处理:
编辑:在与bbum进行深入讨论后,修改了以下方法并正确考虑了多线程。
- (void)contextDidSave:(NSNotification *)notification
{
SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
[[[[UIApplication sharedApplication] delegate] managedObjectContext] performSelectorOnMainThread:selector withObject:notification waitUntilDone:YES];
}
对于UI更新,可以使用NSFetchedResultsController
委托方法自动完成。
最后,请记住添加以下dealloc
的{{1}}方法:
NSFetchedResultsController
答案 1 :(得分:2)
Unforgiven的答案无法正确处理线程。特别是,文件说明(强调我的):
如果您的应用程序有图形 用户界面,建议 您收到与用户相关的事件和 启动您的界面更新 应用程序的主要线程。这个 方法有助于避免同步 与处理用户相关的问题 事件和绘图窗口内容。 一些框架,例如Cocoa, 通常需要这种行为,但是 即使是那些不这样做,保持 主线程上的这种行为有 简化逻辑的优点 用于管理用户界面。
通知观察员将首先针对发布通知的任何线程触发。因此,您无法直接从后台线程发布的通知中调用NSTableView的reloadData
。
根本不需要使用通知。在后台线程中,当准备好更新用户界面时,使用许多机制中的任何一种来重新加载主线程中的数据 - 在管理主事件循环的线程中。用户界面。
[tableView performSelectorOnMainThread: @selector(reloadData)
withObject: nil waitUntilDone: YES];
您也可以使用Grand Central Dispatch或NSOperation做类似的事情。