UIManagedDocument: How to perform saving in background
我有一个连接到NSFetchedResultsController的表视图,并且对应的managedObjectContext是self.myDatabase.managedObjectContext:
1 2 3 4 | self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.myDatabase.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; |
现在,每当用户刷新页面时,我都会执行以下代码。本质上,我创建了一个新线程来加载数据,然后在MOC安全线程上更新/保存新数据:
1 2 3 4 5 6 7 8 9 10 11 | dispatch_queue_t fetchQ = dispatch_queue_create("fetcher", NULL); dispatch_async(fetchQ, ^{ NSArray *data = [MyAPI myData]; [document.managedObjectContext performBlock:^{ for (NSDictionary *info in data) { [MyEntity createOrUpdateGivenInfo:info andManagedObjectContext:self.myDatabase.managedObjectContext]; } }]; }); dispatch_release(fetchQ); |
这正常工作:我得到了更新,并且表格视图正确显示了所有内容。唯一的问题是UI没有响应,大概是因为我在主线程上进行了保存/更新。因此,我考虑使用此修改在后台线程上执行该操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init WithConcurrencyType:NSPrivateQueueConcurrencyType]; [backgroundContext setParentContext:self.myDatabase.managedObjectContext]; [backgroundContext performBlock:^{ NSArray *data = [MyAPI myData]; for (NSDictionary *info in data) { [MyEntity createOrUpdateGivenInfo:info andManagedObjectContext:backgroundContext]; } [backgroundContext save:nil]; [document.managedObjectContext performBlock:^{ [document updateChangeCount:UIDocumentChangeDone]; }]; }]; |
但是,现在UI响应时,我在表视图中遇到了很多麻烦:该表显示了一个额外的条目(而不应该存在重复项),而不是更新现有条目。我认为可能是因为这两个上下文未同步/合并,但是通过阅读以前的SO帖子,我被认为是我只需要在backgroundContext上调用save,然后在主MOC上调用updateChangeCount。
如果我重新启动该应用程序,一切将再次正常运行-直到我再次刷新。
有人有帮助吗?我真的开始拔头发。
如果您能解决这个谜团,我会给您喝啤酒。
像您一样将
读/写在后台线程上自动进行。
如果您需要做一些繁重的工作,则可以创建另一个
我阅读了您的代码,看来这就是您所做的,并且应该可以正常工作。这正是我在应用程序中执行的方式。但是我看到其他人报告
如果您愿意分享您的项目,我来看一下。