核心数据后台同步冲突问题

时间:2010-06-28 14:49:07

标签: iphone uitableview core-data

在使用Core Data开发iPhone应用程序时,我遇到了崩溃问题。

该应用程序与后台线程上的Web服务同步数据。

当应用程序首次启动时,Core Data DB中的现有数据将在UITableView中显示给用户,而后台线程将从Web服务API获取最新数据。让我们调用核心数据模型User和Items,仅用于具有许多项目的用户的讨论目的。这些项目是UITableView中显示的内容。

当API结果返回时,将从Core数据中删除用户现有的Item记录,并将新的Item记录集插入到Core Data中。解析完所有项目后,会将一条消息发送回主线程以合并核心数据更改并从CD中重新获取数据。

但是,我一直在我的配置表单元格例程中崩溃,我确定它是因为超出了范围对象。意思是,主线程试图从Core Data显示对象,而后台线程正在从Core数据中删除那些相同的对象并用新的替换它们。

处理这类冲突的最佳方法是什么?在主视图加载/显示其所有数据之前,是否必须设置某种机制才能启动后台线程更新?如果是这样,我该如何做到这一点?我可以保持相同的方法并更好地处理删除显示的项目吗?

6 个答案:

答案 0 :(得分:1)

请参阅TopSongs项目SongsViewController实现 具体为viewDidLoadhandleSaveNotification

- (void)handleSaveNotification:(NSNotification *)aNotification {
[managedObjectContext mergeChangesFromContextDidSaveNotification:aNotification];
[self fetch];
}

您的viewController的handleSaveNotification:未被调用,因为您已注册来自其拥有的MOC的通知,而不是所有MOC的通知。它适用于TopSongs示例,因为app委托和viewController的MOC是同一个对象。 (appDelegate将moc传递给songsViewController)。

替换:

// ViewController.m viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];

使用:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil];

替换:

// ViewController.m viewDidUnload
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];

使用:

[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:nil];

答案 1 :(得分:0)

那些核心数据操作是否如此昂贵以至于您无法从主线程执行此操作?只需在另一个线程上执行webservice部分。否则,它可能会变得更加困难 - 可能会在其间放置一些控制器类来缓存相关数据或同步对Core Data的访问。

答案 2 :(得分:0)

您如何访问表中的数据?如果您使用的是NSFetchedResultsController,则应该以安全的方式自动更新单元格。

在原始问题的范围内:
除非您的数据保存在其他位置,否则在滚动表格时重新绘制单元格会访问数据。您可以复制您用于填充单元格的所有数据,但这会增加您的内存使用量。

答案 3 :(得分:0)

主线程和后台线程是否都使用自己的Core Data托管对象上下文?您还可以查看

中的核心数据多线程技巧

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdMultiThreading.html

答案 4 :(得分:0)

检查您的NSFetchedResultsControllerDelegate方法controllerWillChangeContent:controllerDidChangeContent:

您有责任通过beginUpdatesendUpdates消息通知表格您要更改它。当获取的结果控制器要修改返回的数据时,表需要冻结更新,直到控制器完成。否则,该表正试图表示不断变化的数据列表。

答案 5 :(得分:0)

你解决了吗?

检查一下你 a)不使用缓存 - 即最初创建FRC时的调用不使用缓存:

 NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]

(参见cacheName:nil)

b)你在FRC中使用谓词吗?我现在遇到各种各样的问题,尝试做与你的代码相同的事情。