CoreData SIGABRT 同时保存主 MOC。为啥?
Posted
技术标签:
【中文标题】CoreData SIGABRT 同时保存主 MOC。为啥?【英文标题】:CoreData SIGABRT while saving main MOC. Why?CoreData SIGABRT 同时保存主 MOC。为什么? 【发布时间】:2014-05-03 16:05:28 【问题描述】:我对保存主要 MOC 时遇到的崩溃感到非常困惑:
-(void) saveMainMOC
[_mainMOC performBlockAndWait:^
NSError *errMain=nil;
NSMutableArray *objs = [NSMutableArray array];
for (NSManagedObject *obj in [[[_mainMOC insertedObjects] allObjects] arrayByAddingObjectsFromArray:[[_mainMOC updatedObjects] allObjects]])
if (obj)
[objs addObject:obj];
if (![_mainMOC obtainPermanentIDsForObjects:objs error:&errMain])
NSLog(@"MainViewController::saveMainMOC.obPeID");
if (![_mainMOC save:&errMain]) // THE SIGABRT OCCURS HERE
NSLog(@"MainViewController::saveMainMOC.saveMain");
];
这是异常和堆栈跟踪:
2014-05-03 17:52:27.317 uRSS[4060:60b] *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x9c31690 <x-coredata://9092A9F4-DAE0-4413-AADF-E137FBB3A860/Post/p1128>''
*** First throw call stack:
(
0 CoreFoundation 0x028fd1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01faf8e5 objc_exception_throw + 44
2 CoreData 0x01c80beb _PFFaultHandlerLookupRow + 2715
3 CoreData 0x01c80147 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
4 CoreData 0x01c7fd23 _PF_FulfillDeferredFault + 259
5 CoreData 0x01c8c0a9 _PF_Handler_WillAccess_Property + 57
6 CoreData 0x01c8beda _PF_ManagedObject_WillChangeValueForKeyIndex + 74
7 CoreData 0x01c8f4c7 _sharedIMPL_setvfk_core + 151
8 CoreData 0x01cc0d06 -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) _setGenericValue:forKey:withIndex:flags:] + 54
saveMainMOC
方法是从下面的saveLocalMOC
方法调用的:
-(void)saveLocalMOC
[_localMOC performBlockAndWait:^
NSError *errLoc=nil;
NSMutableArray *objs = [NSMutableArray array];
for (NSManagedObject *obj in [[[_localMOC insertedObjects] allObjects] arrayByAddingObjectsFromArray:[[_mainMOC updatedObjects] allObjects]])
if (obj)
[objs addObject:obj];
if (![_localMOC obtainPermanentIDsForObjects:objs error:&errLoc])
NSLog(@"MainViewController::saveLocalMOC.obPeID");
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(_localMOCDidSave:)
name:NSManagedObjectContextDidSaveNotification object:_localMOC];
if (![_localMOC save:&errLoc])
NSLog(@"MainViewController::saveLocalMOC.saveLocal");
[nc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:_localMOC];
[self saveMainMOC];
];
注意:如果我从两个过程中删除 obtainPermanentIDsForObjects
,它也会崩溃。
这里也是_localMOCDidSave
观察者。
- (void)_localMOCDidSave:(NSNotification *)notification
if (_mainMOC)
[_mainMOC performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification waitUntilDone:YES];
我真的被这一切弄糊涂了,我做错了什么?
主 MOCS 和本地 MOCS 以这种方式初始化:
_mainMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainMOC setParentContext:_saveMOC];
[_mainMOC setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
self.localMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[self.localMOC setParentContext:self.mainMOC];
[self.localMOC setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
saveMOC 就是这样创建的:
_saveMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_saveMOC setPersistentStoreCoordinator:coordinator];
该错误通常出现在数百条帖子记录的初始加载期间。
【问题讨论】:
core data child/parent save exception的可能重复 【参考方案1】:(部分)修复here:
我就是这样解决的:
[_mocInMemoryForDynamicInformation.parentContext obtainPermanentIDsForObjects:@[session] error:&error];
【讨论】:
以上是关于CoreData SIGABRT 同时保存主 MOC。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
删除 CoreData 对象,然后调用 [tableView reloadData] 会导致 SIGABRT