在使用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