我的情况是通过回调函数每秒一个接一个地来找我200多个对象,显然我不能在这个回调函数中每次都保存一个实体,这会导致UI挂起,所以我的问题是如何插入具有核心数据的批处理数据?
编辑:
谢谢,伙计们,我这样重新编辑我的代码,还有一些问题, 如果我经常从回调函数收到“1”,“2”,“3”......我的tableview经常显示“1”,“3”,“2”......,它们的顺序错误。如果有什么不对的地方,请告诉我。
在AppDelegate.m文件中:
- (NSManagedObjectContext *)mainManagedObjectContext {
if (_ mainManagedObjectContext != nil) {
return _managedObjectContext;
}
_mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainManagedObjectContext.parentContext = [self rootManagedObjectContext];
return _mainManagedObjectContext;
}
- (NSManagedObjectContext*)rootManagedObjectContext {
if (_rootManagedObjectContext != nil) {
return _rootManagedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_rootManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_rootManagedObjectContext setPersistentStoreCoordinator:coordinator];
return _rootManagedObjectContext;
}
在回调函数中我这样做,我试图替换_mainManagedObjectContext
使用_rootContext
或_workContext
int回调函数,但数据永远不会显示在tableview上;
- (void)saveChatMessage:(ChatMessage*)msg userInfo:(UserInfo*)user chatType:(ChatType)chatType receiverID:(long long)receiverID receiverName:(NSString*)receiverName
{
ChatObject *chatObject = [NSEntityDescription
insertNewObjectForEntityForName:@"ChatObject"
inManagedObjectContext: _mainManagedObjectContext];
chatObject.receiveTime = [NSNumber numberWithLongLong:[NSDate date].timeIntervalSince1970];
chatObject.text = msg.text;
chatObject.richText = msg.richText;
chatObject.senderID = [NSNumber numberWithLongLong:user.userID];
chatObject.senderName = user.userName;
chatObject.chatType = [NSNumber numberWithInteger:chatType];
chatObject.isFromHost = [NSNumber numberWithBool:user.isOrganizer];
chatObject.receiverID = [NSNumber numberWithLongLong:receiverID];
chatObject.receiverName = receiverName;
NSError *error;
if (![_workerContext save:&error]) {
}
if (![_rootContext save:&error]) {
}
}
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"ChatObject" inManagedObjectContext:_mainManagedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"receiveTime" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:_mainManagedObjectContext sectionNameKeyPath:nil
cacheName:@"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
答案 0 :(得分:2)
您必须使用背景上下文。我推荐这个设置:
RootContext (background) for saving --> is parent of
MainContext (main thread) for UI --> is parent of
WorkerContext (background) for insert, update, delete operations
应在应用开始时设置根上下文和主要上下文。您可以在Web回调中创建工作线程上下文(当您有新数据可用时),然后将上下文与块API一起使用:
workerContext.performBlock() {
// update data here
}
当您在工作人员上下文中调用save()
时,UI上下文会获得更改并可以优雅地更新自身(例如,通过NSFetchedResultsControllerDelegate
)。确保还在根上下文中调用save以将数据持久保存到持久性存储中。
这是一个好方法的基本概要。如果您不熟悉上述某些技术,可以在此平台上找到许多这些技术的详细解释。
答案 1 :(得分:0)
您可以在后台线程中插入所有数据,并在完成后保存上下文 - 这将更新其他线程中的上下文。只需注意所有保存都在后台线程上完成,以避免并发问题。