在使用Core Data开发iPhone应用程序时,我遇到了崩溃问题。
该应用程序与后台线程上的Web服务同步数据。
当应用程序首次启动时,Core Data DB中的现有数据将在UITableView中显示给用户,而后台线程将从Web服务API获取最新数据。让我们调用核心数据模型User和Items,仅用于具有许多项目的用户的讨论目的。这些项目是UITableView中显示的内容。
当API结果返回时,将从Core数据中删除用户现有的Item记录,并将新的Item记录集插入到Core Data中。解析完所有项目后,会将一条消息发送回主线程以合并核心数据更改并从CD中重新获取数据。
但是,我一直在我的配置表单元格例程中崩溃,我确定它是因为超出了范围对象。意思是,主线程试图从Core Data显示对象,而后台线程正在从Core数据中删除那些相同的对象并用新的替换它们。
处理这类冲突的最佳方法是什么?在主视图加载/显示其所有数据之前,是否必须设置某种机制才能启动后台线程更新?如果是这样,我该如何做到这一点?我可以保持相同的方法并更好地处理删除显示的项目吗?
答案 0 :(得分:1)
请参阅TopSongs项目SongsViewController实现
具体为viewDidLoad
和handleSaveNotification
- (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托管对象上下文?您还可以查看
中的核心数据多线程技巧答案 4 :(得分:0)
检查您的NSFetchedResultsControllerDelegate方法controllerWillChangeContent:
和controllerDidChangeContent:
。
您有责任通过beginUpdates
和endUpdates
消息通知表格您要更改它。当获取的结果控制器要修改返回的数据时,表需要冻结更新,直到控制器完成。否则,该表正试图表示不断变化的数据列表。
答案 5 :(得分:0)
你解决了吗?
检查一下你 a)不使用缓存 - 即最初创建FRC时的调用不使用缓存:
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]
(参见cacheName:nil)
b)你在FRC中使用谓词吗?我现在遇到各种各样的问题,尝试做与你的代码相同的事情。