核心数据多线程

时间:2010-04-14 12:04:44

标签: iphone cocoa cocoa-touch core-data

我的应用程序首先提供一个tableview,其数据源是Core Data SQLite存储。当应用程序启动时,会创建一个具有自己的商店控制器和上下文的辅助线程,以便从Web获取商店中数据的更新。但是,对存储的任何结果更改都不会通知给fetchedresults控制器(我假设它有自己的协调器),因此表不会随存储更改而更新。刷新主线程上下文的最有效方法是什么?我正在考虑跟踪辅助线程上更改的任何对象的objectID,在辅助线程完成时将它们发送到主线程并调用“[context refreshObject:....]任何帮助都将非常感谢。

2 个答案:

答案 0 :(得分:2)

NSFetchedResultsController处理该表格时,请在viewDidLoadloadView注册以获取通知:

[[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做类似的事情。