本文介绍了删除对象在后台moc然后刷新它在主moc导致崩溃在NSFetchedResultsController更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个不能理解的 NSObjectInaccessibleException

  ***因未捕获异常NSObjectInaccessibleException而终止应用程序,原因:CoreData无法为'0x8c40040< x-coredata:// 85B02C1C-1FFC-4CBF-B7AC-EEA259115427 / Event / p6> b $ b ***第一掷调用堆栈:

0的CoreFoundation 0x01aa15e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018248b6 objc_exception_throw + 44
2 CoreData 0x0025733b _PFFaultHandlerLookupRow + 2715
3 CoreData 0x00256897 - [NSFaultHandler fulfillFault:withContext:forIndex:] + 39
4 CoreData 0x00256473 _PF_FulfillDeferredFault + 259
5 CoreData 0x002562c6 _sharedIMPL_pvfk_core + 70
6 CoreData 0x0025acd5 - [NSManagedObject( _PFDynamicAccessorsAndPropertySupport)_genericValueForKey:withIndex:标志:] + 85
7 CoreData 0x00294781 _PF_Handler_Public_GetProperty + 161
8 CoreData 0x00294685 - [NSManagedObject valueForKey:] + 149
9基金会0x01471a5a - [NSObject的(即NSKeyValueCoding)valueForKeyPath :] + 409
10基础0x015079ba - [NSSortDescriptor compareObject:toObject:] + 166
11 CoreData 0x00366175 + [NSFetchedResultsController(PrivateMethods)_insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 309
12分配CoreData 0x00360f61 - [NSFetchedResultsController(PrivateMethods)_postprocessInsertedObjects:] + 737
13 CoreData 0x00362c44 - [NSFetchedResultsController(PrivateMethods)_postprocessUpdatedObjects:] + 916
14 CoreData 0x00363578 - [NSFetchedResultsController(PrivateMethods)_managedObjectContextDidChange:] + 2152
15基金会0x014f7bf9 __57- [NSNotificationCenter的addObserver:选择:名称:对象:] _ block_invoke + 40
16的CoreFoundation 0x01afd524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
17的CoreFoundation 0x01a5500b _CFXNotificationPost + 2859
18基金0x01431951 - [NSNotificationCenter postNotificationName:对象:用户信息:] + 98
19 CoreData 0x00268173 - [的NSManagedObjectContext(_NSInternalNotificationHandling)_postObjectsDidChangeNotificationWithUserInfo:] + 83
20 CoreData 0x0030778f - [的NSManagedObjectContext(_NSInternalChangeProcessing)_createAndPostChangeNotification:withDeletions:withUpdates: + Core $ 0x00263e38 - [NSManagedObjectContext(_NSInternalChangeProcessing)_postRefreshedObjectsNotificationAndClearList] + 136
CoreData 0x002639e4 - [NSManagedObjectContext(_NSInternalChangeProcessing)_processRecentChanges:] + 3140
23 CoreData 0x00262d99 - [NSManagedObjectContext processPendingChanges] + 41
24 CoreData 0x00236fe1 _performRunLoopAction + 321
25 CoreFoundation 0x01a694ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
26 CoreFoundation 0x01a6941f __CFRunLoopDoObservers + 399
27 CoreFoundation 0x01a47344 __CFRunLoopRun + 1076
28 CoreFoundation 0x01a46ac3 CFRunLoopRunSpecific + 467
29 CoreFoundation 0x01a468db CFRunLoopRunInMode + 123
30 GraphicsServices 0x039029e2 GSEventRunModal + 192
31 GraphicsServices 0x03902809 GSEventRun + 104
32 UIKit 0x00592d3b UIApplicationMain + 1225
33 RefreshDeletedTest 0x00005d9d main + 141
34 libdyld.dylib 0x020df70d start + 1

libc ++ abi.dylib:以_NSCoreDataException类型的未捕获异常终止

这是由特定代码流引起的:

   - (void)deleteObject:(NSManagedObject *)object {
NSManagedObjectID * objID = object.objectID;
NSManagedObjectContext * dataProcessingMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
dataProcessingMoc.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;
dataProcessingMoc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataProcessingContextDidSave :) name:NSManagedObjectContextDidSaveNotification object:dataProcessingMoc];
//如果我使用performBlockAndWait:而不是performBlock:问题消失。
[dataProcessingMoc performBlock:^ {
NSManagedObject * objInDPMoc = [dataProcessingMoc objectWithID:objID];
NSLog(@Delete:%@,objInDPMoc);
[dataProcessingMoc deleteObject:objInDPMoc]; // 1
[object.managedObjectContext performBlockAndWait:^ {
[object.managedObjectContext refreshObject:object mergeChanges:NO]; // 2
}];
[dataProcessingMoc save:NULL]; // 3
}];
}

- (void)dataProcessingContextDidSave:(NSNotification *)note {
NSManagedObjectContext * moc = self.managedObjectContext;
[moc performBlockAndWait:^ {// 3
[moc mergeChangesFromContextDidSaveNotification:note];
NSError * error;
if([moc hasChanges]&&![moc save:& error]){
NSLog(@Unresolved error%@,error);
abort();
}
}];
}

注意:代码必须看起来很奇怪, 。


  1. 在背景moc中删除一个对象。

  2. 刷新同一个对象,以在主moc中变成错误。

  3. 保存背景moc,并使用<$ c $将其更改合并到主moc c> NSManagedObjectContextDidSaveNotification 。

异常发生在真正的合并之前, c $ c> performBlockAndWait:。



这是moc在崩溃时的线程堆栈:



#0 0x02210fb6 in semaphore_wait_trap()
#1 0x01e3ccde in _dispatch_thread_semaphore_wait()
#2 0x01e3a516 in _dispatch_barrier_sync_f_slow()
# 3 / 0x0007b5 in - [MasterViewController dataProcessingContextDidSave:] at / Users / an0 / dev / Projects / iOS / Study / 3/4 / RefreshDeletedTest / RefreshDeletedTest / MasterViewController.m:84
#6 0x014f7bf9 in __57- [NSNotificationCenter addObserver:selector:name:object:] _ block_invoke()
#7 0x01afd524 in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__()
#8 0x01a5500b in _CFXNotificationPost()
#9 0x01431951 in - [NSNotificationCenter postNotificationName:object:userInfo:]()
#10 0x0027bb2c in - [NSManagedObjectContext(_NSInternalAdditions)_didSaveChanges]()
#11 0x0026720f in - [NSManagedObjectContext save:]()
#12 0x0000345a in __37- [MasterViewController cleanObjects:] _ block_invoke at /Users/an0/dev/Projects/iOS/Study/RefreshDeletedTest/RefreshDeletedTest/MasterViewController.m:78
#13 0x003047c3 in developerSubmittedBlockToNSManagedObjectContextPerform_privateasync()
#14 0x01e4d4b0在_dispatch_client_callout()
#15 0x01e3b07f在_dispatch_queue_drain()
#16 0x01e3ae7a在_dispatch_queue_invoke()
#17 0x01e3be1f _dispatch_root_queue_drain()
#18 0x01e3c137 in _dispatch_worker_thread2()
#19 0x021d9dab在_pthread_wqthread()


$ b b

为什么会以这种方式崩溃?是我的代码真的错了还是它是核心数据的错误?



另一个奇怪的事情,我不能理解是在这样的崩溃后,应用程序无法再发射,因为它会在启动时崩溃:

  2014-01- 0512:31:34.151 RefreshDeletedTest [3546:70b] ***由于未捕获异常NSObjectInaccessibleException而终止应用程序,原因:CoreData无法为'0xa88d060< x-coredata:// 93009ECF-EC6E-4B12 -BC40-997C4BF3B8DF / Event / p11>''
***第一次调用堆栈:

0 CoreFoundation 0x01aa05e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018238b6 objc_exception_throw + 44
CoreData 0x0025633b _PFFaultHandlerLookupRow + 2715
3 CoreData 0x00255897 - [NSFaultHandler fulfillFault:withContext:forIndex:] + 39
4 CoreData 0x00255473 _PF_FulfillDeferredFault + 259
5 CoreData 0x002552c6 _sharedIMPL_pvfk_core + 70
6 CoreData 0x00259cd5 - [NSManagedObject(_PFDynamicAccessorsAndPropertySupport)_genericValueForKey:withIndex:flags:] + 85
CoreData 0x00293781 _PF_Handler_Public_GetProperty + 161
8 CoreData 0x00293685 - [NSManagedObject valueForKey:] + 149
9 Foundation 0x014a8f0a - [NSArray(NSKeyValueCoding)valueForKey:] + 456
10基础0x01470a5a - [NSObject(NSKeyValueCoding)valueForKeyPath:] + 409
11基础0x0149b99d - [NSArray(NSKeyValueCoding)valueForKeyPath:] + 580
12 CoreData 0x0035b7e9 - [NSFetchedResultsController performFetch:] + 697
13 RefreshDeletedTest 0x00003910 - [MasterViewController fetchedResultsController] + 800
14 RefreshDeletedTest 0x0000307e - [MasterViewController numberOfSectionsInTableView:] + 78
15 UIKit 0x007e5b94 - [UITableViewRowData(UITableViewRowDataPrivate)_updateNumSections] + 102
16 UIKit 0x007e6993 - [UITableViewRowData invalidateAllSections] + 69
17 UIKit 0x0065d237 - [UITableView _updateRowData] + 194
18 UIKit 0x0065d170 - UITableView _ensureRowDataIsLoaded] + 45
19 UIKit 0x006704b3 - [UITableView numberOfSections] + 35
20 UIKit 0x0084d3d3 - [UITableViewController viewWillAppear:] + 103
21 UIKit 0x006a8bfa - [UIViewController _setViewAppearState:isAnimating:] + 419
22 UIKit 0x006a9108 - [UIViewController __viewWillAppear:] + 114
23 UIKit 0x006cb3f5 - [UINavigationController _startTransition:fromViewController:toViewController:] + 800
24 UIKit 0x006cc09c - [UINavigationController _startDeferredTransitionIfNeeded:] + 645
25 UIKit 0x006cccb9 - [UINavigationController __viewWillLayoutSubviews] + 57
26 UIKit 0x00806181 - [UILayoutContainerView layoutSubviews] + 213
27 UIKit 0x0e35656f - [UILayoutContainerViewAccessibility(SafeCategory)layoutSubviews] + 50
28 UIKit 0x005fc267 - [UIView(CALayerDelegate)layoutSublayersOfLayer:] + 355
29 libobjc.A.dylib 0x0183581f - [NSObject performSelector:withObject:] + 70
30 QuartzCore 0x045802ea - [CALayer layoutSublayers] + 148
31 QuartzCore 0x045740d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
32 QuartzCore 0x04580235 - [CALayer layoutIfNeeded] + 160
33 UIKit 0x006b7613 - [UIViewController window:setupWithInterfaceOrientation:] + 304
34 UIKit 0x005d6177 - [UIWindow _setRotatableClient :toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
35 UIKit 0x005d4d16 - [UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
36 UIKit 0x005d4be8 - [UIWindow _setRotatableViewOrientation:updateStatusBar :duration:force:] + 117
37 UIKit 0x005d4c70 - [UIWindow _setRotatableViewOrientation:duration:force:] + 67
38 UIKit 0x005d3d0a __57- [UIWindow _updateToInterfaceOrientation:duration:force:] _ block_invoke + 120
39 UIKit 0x005d3c6c - [UIWindow _updateToInterfaceOrientation:duration:force:] + 400
40 UIKit 0x005d49c3 - [UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
41 UIKit 0x005d7fb6 - [UIWindow setDelegate:] + 449
42 UIKit 0x006a9737 - [UIViewController _tryBecomeRootViewControllerInWindow:] + 180
43 UIKit 0x005cdc1c - [UIWindow addRootViewControllerViewIfPossible] + 609
44 UIKit 0x005cdd97 - [UIWindow _setHidden:forced:] + 312
45 UIKit 0x005ce02d - [UIWindow _orderFrontWithoutMakingKey] + 49
46 UIKit 0x0e332c66 - [UIWindowAccessibility(SafeCategory)_orderFrontWithoutMakingKey] + 77
47 UIKit 0x005d889a - [UIWindow makeKeyAndVisible] + 65
48 UIKit 0x0058bcd0 - [UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
49 UIKit 0x005903a8 - [UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
50 UIKit 0x005a487c - [UIApplication handleEvent:withNewEvent:] + 3447
51 UIKit 0x005a4de9 - [UIApplication sendEvent:] + 85
52 UIKit 0x00592025 _UIApplicationHandleEvent + 736
53 GraphicsServices 0x039032f6 _PurpleEventCallback + 776
54 GraphicsServices 0x03902e01 PurpleEventCallback + 46
55 CoreFoundation 0x01a1bd65 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
56的CoreFoundation 0x01a1ba9b __CFRunLoopDoSource1 + 523
57的CoreFoundation 0x01a4677c __CFRunLoopRun + 2156
58的CoreFoundation 0x01a45ac3 CFRunLoopRunSpecific + 467
59的CoreFoundation 0x01a458db CFRunLoopRunInMode + 123
60的UIKit 0x0058fadd - [UIApplication _run] + 840
61 UIKit 0x00591d3b UIApplicationMain + 1225
62 RefreshDeletedTest 0x0000508d main + 141
63 libdyld.dylib 0x020de70d start + 1

libc ++ abi.dylib:以_NSCoreDataException类型的未捕获异常结束

自行查看问题:

解决方案

在多线程环境中,无法避免此问题。



只要在同一层次结构级别上有2个不同的上下文(无论是父子结构还是直接连接到存储),您可能会遇到一个上下文删除对象(以及对存储提交的更改)和其他一个尝试在更改合并之前访问此对象。

当父上下文提交更改到存储,并且其子项尝试访问作为错误保存的已删除项目时,也可能会发生这种情况。 $ b一般来说,在提交之前不会在上下文之间自动传播更改的每个地方,都有机会获得此异常。



如果你可以传递你的上下文(store-context1-context2 -...),并且只从链中的最终上下文中删除你可以避免这个问题。



您可以设计一些算法来延迟您的删除操作,因此只有在没有其他上下文使用特定项目时,才会提交这些算法,但这涉及到您的部分上的很多记录。



您可以通过提取完整的(无故障的)对象或整个将要使用的子图(使用FRC时无法完成)来减少上下文之间的冲突,并对这些对象进行操作。 br />


I encountered an NSObjectInaccessibleException that I can not understand:

 *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x8c40040 <x-coredata://85B02C1C-1FFC-4CBF-B7AC-EEA259115427/Event/p6>''
*** First throw call stack:
(
    0   CoreFoundation                      0x01aa15e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x018248b6 objc_exception_throw + 44
    2   CoreData                            0x0025733b _PFFaultHandlerLookupRow + 2715
    3   CoreData                            0x00256897 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
    4   CoreData                            0x00256473 _PF_FulfillDeferredFault + 259
    5   CoreData                            0x002562c6 _sharedIMPL_pvfk_core + 70
    6   CoreData                            0x0025acd5 -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) _genericValueForKey:withIndex:flags:] + 85
    7   CoreData                            0x00294781 _PF_Handler_Public_GetProperty + 161
    8   CoreData                            0x00294685 -[NSManagedObject valueForKey:] + 149
    9   Foundation                          0x01471a5a -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 409
    10  Foundation                          0x015079ba -[NSSortDescriptor compareObject:toObject:] + 166
    11  CoreData                            0x00366175 +[NSFetchedResultsController(PrivateMethods) _insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 309
    12  CoreData                            0x00360f61 -[NSFetchedResultsController(PrivateMethods) _postprocessInsertedObjects:] + 737
    13  CoreData                            0x00362c44 -[NSFetchedResultsController(PrivateMethods) _postprocessUpdatedObjects:] + 916
    14  CoreData                            0x00363578 -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 2152
    15  Foundation                          0x014f7bf9 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
    16  CoreFoundation                      0x01afd524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
    17  CoreFoundation                      0x01a5500b _CFXNotificationPost + 2859
    18  Foundation                          0x01431951 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98
    19  CoreData                            0x00268173 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 83
    20  CoreData                            0x0030778f -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] + 367
    21  CoreData                            0x00263e38 -[NSManagedObjectContext(_NSInternalChangeProcessing) _postRefreshedObjectsNotificationAndClearList] + 136
    22  CoreData                            0x002639e4 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 3140
    23  CoreData                            0x00262d99 -[NSManagedObjectContext processPendingChanges] + 41
    24  CoreData                            0x00236fe1 _performRunLoopAction + 321
    25  CoreFoundation                      0x01a694ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
    26  CoreFoundation                      0x01a6941f __CFRunLoopDoObservers + 399
    27  CoreFoundation                      0x01a47344 __CFRunLoopRun + 1076
    28  CoreFoundation                      0x01a46ac3 CFRunLoopRunSpecific + 467
    29  CoreFoundation                      0x01a468db CFRunLoopRunInMode + 123
    30  GraphicsServices                    0x039029e2 GSEventRunModal + 192
    31  GraphicsServices                    0x03902809 GSEventRun + 104
    32  UIKit                               0x00592d3b UIApplicationMain + 1225
    33  RefreshDeletedTest                  0x00005d9d main + 141
    34  libdyld.dylib                       0x020df70d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type _NSCoreDataException

It is caused by a specific code flow:

- (void)deleteObject:(NSManagedObject *)object {
    NSManagedObjectID *objID = object.objectID;
    NSManagedObjectContext *dataProcessingMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    dataProcessingMoc.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;
    dataProcessingMoc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataProcessingContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:dataProcessingMoc];
    // If I use performBlockAndWait: instead of performBlock: the issue goes away.
    [dataProcessingMoc performBlock:^{
        NSManagedObject *objInDPMoc = [dataProcessingMoc objectWithID:objID];
        NSLog(@"Delete: %@", objInDPMoc);
        [dataProcessingMoc deleteObject:objInDPMoc]; // 1
        [object.managedObjectContext performBlockAndWait:^{
            [object.managedObjectContext refreshObject:object mergeChanges:NO]; // 2
        }];
        [dataProcessingMoc save:NULL]; // 3
    }];
}

- (void)dataProcessingContextDidSave:(NSNotification *)note {
    NSManagedObjectContext *moc = self.managedObjectContext;
    [moc performBlockAndWait:^{ // 3
        [moc mergeChangesFromContextDidSaveNotification:note];
        NSError *error;
        if ([moc hasChanges] && ![moc save:&error]) {
            NSLog(@"Unresolved error %@", error);
            abort();
        }
    }];
}

Note: the code must look weird and does not make much sense. It is the result of my reducing real code to the minimum bug-reproducing code.

  1. Delete an object in background moc.
  2. Refresh the same object to turned into a fault in main moc.
  3. Save background moc and merge its changes to main moc using NSManagedObjectContextDidSaveNotification.

The exception occurs before the real merge, at the main moc's call of performBlockAndWait:.

Here is the background moc's thread stack at the time of crash:

#0  0x02210fb6 in semaphore_wait_trap ()
#1  0x01e3ccde in _dispatch_thread_semaphore_wait ()
#2  0x01e3a516 in _dispatch_barrier_sync_f_slow ()
#3  0x01e3a413 in dispatch_barrier_sync_f ()
#4  0x0028bf1f in -[NSManagedObjectContext performBlockAndWait:] ()
#5  0x000037b5 in -[MasterViewController dataProcessingContextDidSave:] at /Users/an0/dev/Projects/iOS/Study/RefreshDeletedTest/RefreshDeletedTest/MasterViewController.m:84
#6  0x014f7bf9 in __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke ()
#7  0x01afd524 in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ ()
#8  0x01a5500b in _CFXNotificationPost ()
#9  0x01431951 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#10 0x0027bb2c in -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] ()
#11 0x0026720f in -[NSManagedObjectContext save:] ()
#12 0x0000345a in __37-[MasterViewController cleanObjects:]_block_invoke at /Users/an0/dev/Projects/iOS/Study/RefreshDeletedTest/RefreshDeletedTest/MasterViewController.m:78
#13 0x003047c3 in developerSubmittedBlockToNSManagedObjectContextPerform_privateasync ()
#14 0x01e4d4b0 in _dispatch_client_callout ()
#15 0x01e3b07f in _dispatch_queue_drain ()
#16 0x01e3ae7a in _dispatch_queue_invoke ()
#17 0x01e3be1f in _dispatch_root_queue_drain ()
#18 0x01e3c137 in _dispatch_worker_thread2 ()
#19 0x021d9dab in _pthread_wqthread ()

Why it crashes this way? Is my code really wrong or it is a bug of Core Data?

Another odd thing that I can not understand is that, after such a crash the app can not be launch any more for it will crash on launch:

2014-01-05 12:31:34.151 RefreshDeletedTest[3546:70b] *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xa88d060 <x-coredata://93009ECF-EC6E-4B12-BC40-997C4BF3B8DF/Event/p11>''
*** First throw call stack:
(
    0   CoreFoundation                      0x01aa05e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x018238b6 objc_exception_throw + 44
    2   CoreData                            0x0025633b _PFFaultHandlerLookupRow + 2715
    3   CoreData                            0x00255897 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
    4   CoreData                            0x00255473 _PF_FulfillDeferredFault + 259
    5   CoreData                            0x002552c6 _sharedIMPL_pvfk_core + 70
    6   CoreData                            0x00259cd5 -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) _genericValueForKey:withIndex:flags:] + 85
    7   CoreData                            0x00293781 _PF_Handler_Public_GetProperty + 161
    8   CoreData                            0x00293685 -[NSManagedObject valueForKey:] + 149
    9   Foundation                          0x014a8f0a -[NSArray(NSKeyValueCoding) valueForKey:] + 456
    10  Foundation                          0x01470a5a -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 409
    11  Foundation                          0x0149b99d -[NSArray(NSKeyValueCoding) valueForKeyPath:] + 580
    12  CoreData                            0x0035b7e9 -[NSFetchedResultsController performFetch:] + 697
    13  RefreshDeletedTest                  0x00003910 -[MasterViewController fetchedResultsController] + 800
    14  RefreshDeletedTest                  0x0000307e -[MasterViewController numberOfSectionsInTableView:] + 78
    15  UIKit                               0x007e5b94 -[UITableViewRowData(UITableViewRowDataPrivate) _updateNumSections] + 102
    16  UIKit                               0x007e6993 -[UITableViewRowData invalidateAllSections] + 69
    17  UIKit                               0x0065d237 -[UITableView _updateRowData] + 194
    18  UIKit                               0x0065d170 -[UITableView _ensureRowDataIsLoaded] + 45
    19  UIKit                               0x006704b3 -[UITableView numberOfSections] + 35
    20  UIKit                               0x0084d3d3 -[UITableViewController viewWillAppear:] + 103
    21  UIKit                               0x006a8bfa -[UIViewController _setViewAppearState:isAnimating:] + 419
    22  UIKit                               0x006a9108 -[UIViewController __viewWillAppear:] + 114
    23  UIKit                               0x006cb3f5 -[UINavigationController _startTransition:fromViewController:toViewController:] + 800
    24  UIKit                               0x006cc09c -[UINavigationController _startDeferredTransitionIfNeeded:] + 645
    25  UIKit                               0x006cccb9 -[UINavigationController __viewWillLayoutSubviews] + 57
    26  UIKit                               0x00806181 -[UILayoutContainerView layoutSubviews] + 213
    27  UIKit                               0x0e35656f -[UILayoutContainerViewAccessibility(SafeCategory) layoutSubviews] + 50
    28  UIKit                               0x005fc267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
    29  libobjc.A.dylib                     0x0183581f -[NSObject performSelector:withObject:] + 70
    30  QuartzCore                          0x045802ea -[CALayer layoutSublayers] + 148
    31  QuartzCore                          0x045740d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    32  QuartzCore                          0x04580235 -[CALayer layoutIfNeeded] + 160
    33  UIKit                               0x006b7613 -[UIViewController window:setupWithInterfaceOrientation:] + 304
    34  UIKit                               0x005d6177 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
    35  UIKit                               0x005d4d16 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
    36  UIKit                               0x005d4be8 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
    37  UIKit                               0x005d4c70 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
    38  UIKit                               0x005d3d0a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
    39  UIKit                               0x005d3c6c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
    40  UIKit                               0x005d49c3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
    41  UIKit                               0x005d7fb6 -[UIWindow setDelegate:] + 449
    42  UIKit                               0x006a9737 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
    43  UIKit                               0x005cdc1c -[UIWindow addRootViewControllerViewIfPossible] + 609
    44  UIKit                               0x005cdd97 -[UIWindow _setHidden:forced:] + 312
    45  UIKit                               0x005ce02d -[UIWindow _orderFrontWithoutMakingKey] + 49
    46  UIKit                               0x0e332c66 -[UIWindowAccessibility(SafeCategory) _orderFrontWithoutMakingKey] + 77
    47  UIKit                               0x005d889a -[UIWindow makeKeyAndVisible] + 65
    48  UIKit                               0x0058bcd0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
    49  UIKit                               0x005903a8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
    50  UIKit                               0x005a487c -[UIApplication handleEvent:withNewEvent:] + 3447
    51  UIKit                               0x005a4de9 -[UIApplication sendEvent:] + 85
    52  UIKit                               0x00592025 _UIApplicationHandleEvent + 736
    53  GraphicsServices                    0x039032f6 _PurpleEventCallback + 776
    54  GraphicsServices                    0x03902e01 PurpleEventCallback + 46
    55  CoreFoundation                      0x01a1bd65 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
    56  CoreFoundation                      0x01a1ba9b __CFRunLoopDoSource1 + 523
    57  CoreFoundation                      0x01a4677c __CFRunLoopRun + 2156
    58  CoreFoundation                      0x01a45ac3 CFRunLoopRunSpecific + 467
    59  CoreFoundation                      0x01a458db CFRunLoopRunInMode + 123
    60  UIKit                               0x0058fadd -[UIApplication _run] + 840
    61  UIKit                               0x00591d3b UIApplicationMain + 1225
    62  RefreshDeletedTest                  0x0000508d main + 141
    63  libdyld.dylib                       0x020de70d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type _NSCoreDataException

Here is the sample project that you can run to see the issues yourself: http://d.pr/f/y3VQ

解决方案

In a multithreaded environment there is no way to avoid this issue.

As long as you have 2 different contexts on the same hierarchy level (be it parent child architecture or directly connected to the store) you might encounter a situation where one context deleted an object (and committed changes to the store) and the other one try to access this object before changes were merged.
This might also happen when parent context commit changes to the store and its child try to access deleted items he hold as faults.
In general, in every place where changes are not propagated automatically between contexts prior to a commit, there is a chance to get this exception.

If you can pipeline your contexts (store-context1-context2-...) and only delete from the final context in the chain you can avoid this issue.

You can devise some algorithm to delay your delete operations so they are committed only when no other context use a specific item, but this involves a lot of bookkeeping on your part.

You can reduce conflicts between your context by fetching full fledged (no faults) objects, or the entire sub-graph you will be working on (cannot be done when using FRC) and make your operations on these objects.

这篇关于删除对象在后台moc然后刷新它在主moc导致崩溃在NSFetchedResultsController更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 12:57