所以我已经阅读了一段时间的堆栈,我意识到我需要制作一个后台核心数据 NSManagedObjectContext
因为我正在加载大量记录并且我不想锁定用户界面。
我所做的如下:
backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
NSPersistentStoreCoordinator *store = [[self managedObjectContext] persistentStoreCoordinator];
[backgroundContext setPersistentStoreCoordinator:store];
在我的函数调用中我直接执行:
self.flightsFRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:backgroundContext
sectionNameKeyPath:nil
cacheName:@"FlightRecords"];
我的代码目前可以正常工作,但我觉得它在其他地方“不好”,我直接访问 FRC 而没有处理任何同步或任何事情,例如我在此处迭代获取结果 Controller 的地方。
FlightRecording *rec = [[[self flightsFRC] fetchedObjects] objectAtIndex:i];
我错过了什么吗?我应该以某种方式通过 NSManagedObjectID
加载记录吗?这似乎“太简单了”
最佳答案
您当前的 FRC 指向后台上下文。不要那样做。仅指向主线程上的上下文。
为了让您的 FRC 收到更改通知,您实际上需要将后台上下文合并到主线程上下文。您的 CoreData 堆栈对象需要在后台上下文保存时注册通知:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
由于通知可以从其他线程发布,我们需要检查何时触发以确保我们在主线程上。如果我们已经在那里,那么我们可以在 NSManagedObjectContext
上调用 mergeChangesFromContextDidSaveNotification
API。
- (void)contextDidSave:(NSNotification *)notification {
if (![NSThread isMainThread]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self contextDidSave:notification];
});
} else {
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
}
由于当主上下文中的数据发生变化时,您的 FRC 正在监听变化,因此 FRC 将触发其回调,以便您可以在 tableview 或 collectionview 中插入/删除/修改记录。
编辑:
听起来您可能没有在后台线程上做任何更改,因为您没有使用后台上下文的 performBlock:
或专用队列来完成工作:
[backgroundContext performBlock:^{
// Do your work
NSError *error = nil;
BOOL success = [backgroundContext save:&error];
// error handling
}];
关于ios - 后台加载核心数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22824583/