在使用NSSortDescriptor对各种属性进行排序后,我想捕获排序顺序并将其保存回核心数据。为了保持uX稳定,我试图在后台使用单独的MOC来完成此操作。但是,我遇到枚举错误时发生了变异,可能是因为其他一些事情正在进行 - 包括与服务器同步并且FRC进行提取。IOS/Objective-C:后台保存到NSFetchedResultsController后的核心数据
任何人都可以看到什么可能是我的代码错了吗?在此先感谢您的任何建议。
-(NSFetchedResultsController *)fetchedResultsController {
//code to carry out fetch
//Sort order specified according to parameters
_theItems =[_fetchedResultsController fetchedObjects];
//at this point fetch should be complete
NSManagedObjectContext *mainMOC = _managedObjectContext;
NSManagedObjectContext*privateContext =[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateContext setParentContext:mainMOC];
[privateContext performBlock:^{
for (int i = 0; i < _theItems.count; i++)
{
Items* oneitem = theItems[i];
oneitem.sortorder = i;
}
NSError *error = nil;
if (![privateContext save:&error]) {
NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
abort();
}
[mainMOC performBlockAndWait:^{
NSError *error = nil;
if (![mainMOC save:&error]) {
NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
//abort();
}
else {
_managedObjectContext = mainMOC;
}
}];
}];
mainMOC=nil;
privateContext = nil;
return _fectchedResultsController;
}
编辑:
从苹果文档:
NSArray *jsonArray = …; //JSON data to be imported into Core Data
NSManagedObjectContext *moc = …; //Our primary context on the main queue
NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[private setParentContext:moc];
[private performBlock:^{
for (NSDictionary *jsonObject in jsonArray) {
NSManagedObject *mo = …; //Managed object that matches the incoming JSON structure
//update MO with data from the dictionary
}
NSError *error = nil;
if (![private save:&error]) {
NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
abort();
}
[moc performBlockAndWait:^{
NSError *error = nil;
if (![moc save:&error]) {
NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
abort();
}
}];
}];
编辑2:
放置在viewdidappear代码停止除外。另外,我将代码更改为以下版本,并且“似乎”正常工作。这是现在线程安全吗?
for (int i = 0; i < _theItems.count; i++)
{
Items* oneitem = theItems[i];
NSManagedObjectID* oneID = oneitem.objectID;
Items *myItem = [privateContext objectWithID:oneID];
myItem.sortorder = i;
}
恐怕这里有些事情是非常错误的。看起来你已经建立了一个私有上下文,然后遍历一组对象(可能是ManagedObject的子类),它们来自哪里?您没有在该方法的任何变体上使用objectWithID检索任何对象,因此您可能正在操纵最初从主上下文中检索到的对象(并在performBlock调用中执行该操作,因此在私有上下文线程 - ouch!上执行该操作)。然后,在错误的线程中操作了来自另一个上下文的对象,您可以尝试保存私有上下文,认为它可以工作。不。 – TheBasicMind
我也读过托管对象不是线程安全的,但对象标识符是这样的,因此您需要使用objectwithID检索所有托管对象。但是,我也读过NSPrivateQueueConcurrencyType似乎已经简化了这个过程,现在可以完成上述操作。也许我误解了。将尝试找到参考。 – user6631314
这是我在文档中阅读:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html – user6631314