NSObjectInaccessbileExceptions while merging child context - ios

I understand about NSObjectInaccessbileExceptions in general, and the need to avoid attempting to fault in an object that has been deleted in another managed context/thread.
However, in my user crash reports, I'm seeing an NSObjectInaccessibleException while merging/saving a child NSManagedObjectContext from a background thread (B) into my main context (A), which seems like an unusual scenario.
The only situation I can imagine that could cause such a thing is the following:
change property of object in thread/context (B)
delete object in thread/context A
save context A
save context B
merge A into B and save A -> exception raised because object doesn't exist in A.
Has anybody else seen an exception in while saving the context like this? I tried to reproduce this manually, but failed. Is there some other scenario where this could happen, and are there any tips for dealing with such?
Thanks!
Fatal Exception
NSObjectInaccessibleException
CoreData could not fulfill a fault for '0x1f019da0 <x-coredata://741E65A8-C211-470E-8194-3005F0DFA71C/TrackInfo/p265>'
0 CoreFoundation __exceptionPreprocess + 162
1 libobjc.A.dylib objc_exception_throw + 30
2 CoreData _PFFaultHandlerLookupRow + 1482
3 CoreData -[NSFaultHandler fulfillFault:withContext:] + 24
4 CoreData -[NSManagedObject(_NSInternalMethods) _updateFromRefreshSnapshot:includingTransients:] + 236
5 CoreData -[NSManagedObjectContext(_NestedContextSupport) _copyChildObject:toParentObject:fromChildContext:] + 96
6 CoreData -[NSManagedObjectContext(_NestedContextSupport) _parentProcessSaveRequest:inContext:error:] + 918
7 CoreData __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke_0 + 564
8 libdispatch.dylib _dispatch_barrier_sync_f_slow_invoke + 96
9 libdispatch.dylib _dispatch_client_callout + 22
10 libdispatch.dylib _dispatch_main_queue_callback_4CF + 228
11 CoreFoundation __CFRunLoopRun + 1288
12 CoreFoundation CFRunLoopRunSpecific + 356
13 CoreFoundation CFRunLoopRunInMode + 104
14 GraphicsServices GSEventRunModal + 74
15 UIKit UIApplicationMain + 1120
16 app main.m line 13 main
17 app start

You may try using the following line while you are creating your child context:
privateManagedObjectContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy

Related

Coredata crash on iOS 16, over-release in -[_PFManagedObjectReferenceQueue _processReferenceQueue:]

We are experiencing a weird issue on iOS16. There is no code change, it works fine on lower OS versions.
The stacktrace is:
The first case
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00000000e5bde410
0
libobjc.A.dylib
objc_release_x21 + 16
1
CoreData
-[_PFManagedObjectReferenceQueue _processReferenceQueue:] + 1020
2
CoreData
-[NSManagedObjectContext _processRecentChanges:] + 112
3
CoreData
_performRunLoopAction + 412
4
CoreFoundation
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
5
CoreFoundation
__CFRunLoopDoObservers + 532
6
CoreFoundation
__CFRunLoopRun + 1048
7
CoreFoundation
CFRunLoopRunSpecific + 612
8
GraphicsServices
GSEventRunModal + 164
9
UIKitCore
-[UIApplication _run] + 888
10
UIKitCore
UIApplicationMain + 340
The second case, I believe this stacktrace has the same root cause as the previous one (same trend, same UI page, only happens on iOS 16).
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0033003200390070
0
libobjc.A.dylib
objc_msgSend + 32
1
CoreFoundation
-[__NSArrayM dealloc] + 188
2
MyApplication
MyClass.m - Line 361
-[MyClass loadMessages:] + 361
3
MyApplication
MyClass.m - Line 125
__74-[MyClass requestRecentMessagesAndDiscardExistingMessagesCompletion:]_block_invoke + 125
4
libdispatch.dylib
_dispatch_call_block_and_release + 32
5
libdispatch.dylib
_dispatch_client_callout + 20
6
libdispatch.dylib
_dispatch_main_queue_drain + 928
7
libdispatch.dylib
_dispatch_main_queue_callback_4CF + 44
8
CoreFoundation
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
9
CoreFoundation
__CFRunLoopRun + 2036
10
CoreFoundation
CFRunLoopRunSpecific + 612
11
GraphicsServices
GSEventRunModal + 164
12
UIKitCore
-[UIApplication _run] + 888
13
UIKitCore
UIApplicationMain + 340
MyClass.m is an Objective-C class, it has a property:
#property (nonatomic, strong) NSArray<Message *> *messages; // Message is NSManagedObject
In the second stacktrace, frame -[OurClass loadMessages:] + 361, the messages array is deallocated:
self.messages = [[NSArray alloc] init...];
So my guess is, somehow the messages are over-released. If the messages are released in MyClass before, then the crash happens as the first stacktrace, otherwise it happens as the second stacktrace.
I've turned on -com.apple.CoreData.ConcurrencyDebug 1 to try to debug this, but no luck.
Any help would be much appreciated. Thanks in advance!

Crash Core Data only in iOS 14

I work on an app which use CoreData, everything works fine on iOS 13 and iOS 14 with differents Xcode betas. But since Apple released the official release for iOS 14 and Xcode 12 I have a crash when I try to get some objects from CoreData.
guard let customers = Customer.mr_findAllSorted(by: "login", ascending: true) as? [Customer] else { return }
Console output :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't get value for 'batch' in bindings {
}.'
When I try to print the object from console log with breakpoint, I have a memory address of object but when I try to print some values of this object I have this error :
error: warning: couldn't get required object pointer (substituting NULL): Couldn't load 'self' because its value couldn't be evaluated
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-5)..
The process has been returned to the state before expression evaluation.
Has anyone ever had to deal with this type of errors since the official versions ?
Thanks in advance for your help.
We're seeing this too in our app. It is only reproducible with iOS 14 and apparently the latest SDKs in Xcode 12.0.1, but we don't have any solutions or answers as to why this is occurring yet.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't get value for 'batch' in bindings {
}.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff2043a126 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff20177f78 objc_exception_throw + 48
2 Foundation 0x00007fff2088bedc -[NSVariableExpression _expressionWithSubstitutionVariables:] + 0
3 Foundation 0x00007fff2075ac7b -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 264
4 CoreData 0x00007fff2511ec68 -[NSDictionaryStoreMap handleFetchRequest:] + 481
5 CoreData 0x00007fff2511dfd2 -[NSMappedObjectStore executeFetchRequest:withContext:] + 230
6 CoreData 0x00007fff251e10a2 __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke.797 + 3219
7 CoreData 0x00007fff251d988d __55-[NSPersistentStoreCoordinator _routeHeavyweightBlock:]_block_invoke + 55
8 CoreData 0x00007fff251edf0a gutsOfBlockToNSPersistentStoreCoordinatorPerform + 182
9 libdispatch.dylib 0x000000010a6b0a88 _dispatch_client_callout + 8
10 libdispatch.dylib 0x000000010a6bfcac _dispatch_lane_barrier_sync_invoke_and_complete + 132
11 CoreData 0x00007fff251d9492 _perform + 169
12 CoreData 0x00007fff251d9740 -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 172
13 CoreData 0x00007fff250d640e -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1684
14 CoreData 0x00007fff250d49c2 -[NSManagedObjectContext executeFetchRequest:error:] + 885
15 CoreData 0x00007fff251a9d7f -[NSManagedObjectContext _parentObjectsForFetchRequest:inContext:error:] + 477
16 CoreData 0x00007fff251aa774 __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 603
17 CoreData 0x00007fff25109de8 internalBlockToNSManagedObjectContextPerform + 89
18 libdispatch.dylib 0x000000010a6b0a88 _dispatch_client_callout + 8
19 libdispatch.dylib 0x000000010a6bfcac _dispatch_lane_barrier_sync_invoke_and_complete + 132
20 CoreData 0x00007fff25109d6f _perform + 196
21 CoreData 0x00007fff25109b93 -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] + 175
22 CoreData 0x00007fff250d49c2 -[NSManagedObjectContext executeFetchRequest:error:] + 885
23 CoreData 0x00007fff251a9d7f -[NSManagedObjectContext _parentObjectsForFetchRequest:inContext:error:] + 477
24 CoreData 0x00007fff251aa774 __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 603
25 CoreData 0x00007fff25109de8 internalBlockToNSManagedObjectContextPerform + 89
26 libdispatch.dylib 0x000000010a6b0a88 _dispatch_client_callout + 8
27 libdispatch.dylib 0x000000010a6bfe11 _dispatch_async_and_wait_invoke + 175
28 libdispatch.dylib 0x000000010a6b0a88 _dispatch_client_callout + 8
29 libdispatch.dylib 0x000000010a6bef23 _dispatch_main_queue_callback_4CF + 1152
30 CoreFoundation 0x00007fff203a8276 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
31 CoreFoundation 0x00007fff203a2b06 __CFRunLoopRun + 2685
32 CoreFoundation 0x00007fff203a1b9e CFRunLoopRunSpecific + 567
33 GraphicsServices 0x00007fff2b773db3 GSEventRunModal + 139
34 UIKitCore 0x00007fff24660af3 -[UIApplication _run] + 912
35 UIKitCore 0x00007fff24665a04 UIApplicationMain + 101
36 XXXX 0x0000000106de2d69 main + 153
37 libdyld.dylib 0x00007fff20257415 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't get value for 'batch' in bindings {
}.'
You may set batch size to 0 [NSManagedObject MR_setDefaultBatchSize:0];, but check you performance after.

Magical Record Crashed: NSManagedObjectContext Queue EXC_BAD_ACCESS KERN_INVALID_ADDRESS

I'm using Magical Record for Core Data operations.
It seems that the crash I posted below would only happen in iOS 7.
And EXC_BAD_ACCESS KERN_INVALID_ADDRESS means some object is deallocated.
I am not quite sure where the bug is.
Any idea on this? Thanks.
Thread : Crashed: NSManagedObjectContext Queue
0 libobjc.A.dylib 0x39d7c636 objc_msgSend + 21
1 Foundation 0x2fee4d9d -[NSError dealloc] + 60
2 libobjc.A.dylib 0x39d81b6b objc_object::sidetable_release(bool) + 174
3 libobjc.A.dylib 0x39d820d7 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
4 CoreFoundation 0x2f4f5c19 _CFAutoreleasePoolPop + 16
5 Foundation 0x2feef637 -[NSAutoreleasePool drain] + 122
6 CoreData 0x2f336fb9 -[NSManagedObjectContext save:] + 944
7 Branch 0x20f87d __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke20 (NSManagedObjectContext+MagicalSaves.m:82)
8 CoreData 0x2f39a935 developerSubmittedBlockToNSManagedObjectContextPerform + 88
9 CoreData 0x2f39aa7b -[NSManagedObjectContext performBlockAndWait:] + 114
10 Branch 0x20f621 -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:] (NSManagedObjectContext+MagicalSaves.m:128)
11 CoreData 0x2f39a935 developerSubmittedBlockToNSManagedObjectContextPerform + 88
12 libdispatch.dylib 0x3a26cdd7 _dispatch_barrier_sync_f_invoke + 26
13 CoreData 0x2f39aa73 -[NSManagedObjectContext performBlockAndWait:] + 106
14 Branch 0x205831 +[MagicalRecord(Actions) saveWithBlockAndWait:] (MagicalRecord+Actions.m:44)
15 Branch 0x1acdbb __62-[BREmployeeDataController getPositionsAtLocation:completion:]_block_invoke (BREmployeeDataController.m:42)
16 Branch 0x1ad87d __66-[BREmployeeDataController synchronizeStaffAtLocation:completion:]_block_invoke (BREmployeeDataController.m:193)
17 Branch 0x1d215b __116-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:uploadProgress:downloadProgress:success:failure:]_block_invoke80 (AFHTTPSessionManager.m:287)
18 Branch 0x1e326b __72-[AFURLSessionManagerTaskDelegate URLSession:task:didCompleteWithError:]_block_invoke_2150 (AFURLSessionManager.m:308)
19 libdispatch.dylib 0x3a25a833 _dispatch_call_block_and_release + 10
20 libdispatch.dylib 0x3a25a81f _dispatch_client_callout + 22
21 libdispatch.dylib 0x3a25a777 _dispatch_main_queue_callback_4CF$VARIANT$up + 254
22 CoreFoundation 0x2f58c8a1 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
23 CoreFoundation 0x2f58b175 __CFRunLoopRun + 1300
24 CoreFoundation 0x2f4f5ebf CFRunLoopRunSpecific + 522
25 CoreFoundation 0x2f4f5ca3 CFRunLoopRunInMode + 106
26 GraphicsServices 0x343fb663 GSEventRunModal + 138
27 UIKit 0x31e4214d UIApplicationMain + 1136
28 Branch 0x1a6437 main (main.m:14)
29 libdyld.dylib 0x3a27fab7 start + 2
Are you using ARC? Does MagicalRecord use ARC?
Either you or MagicalRecord is over-releasing some object that an NSAutoreleasePool believes it owns. Then the pool gets popped (when your NSManagedObjectContext finishes the save: operation) and one of the objects in there is garbage. Try running with NSZombies enabled, or use the Allocations Instrument to determine which object is being over-released.

Override Core Data to-many property and return a filtered set

I’ve got an NSManagedObject with a childNodes property in its model. Now I want to override the childNodes property and return a filtered version of it, but I keep getting crashes. Here’s what I’ve got in my NSMO subclass:
- (NSOrderedSet *)childNodes {
[self willAccessValueForKey:#“childNodes”];
NSMutableOrderedSet *result = [self primitiveChildNodes];
[self didAccessValueForKey:#"childNodes”];
NSArray *filteredResult = [[result array] myCustomArrayFilteringMethod]; // let’s say this returns the first half of the array, as a contrived example
return [NSOrderedSet orderedSetWithArray:filteredResults];
}
This works alright sometimes, but I’m finding crashes like: Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSOrderedSet objectsAtIndexes:]: index 24 in index set beyond bounds [0 .. 19]’ and I’m not sure why. Call stack seems to be related to mutating a collection, but I’m mutating a copy so I’m not sure what’s happening:
0 CoreFoundation __exceptionPreprocess + 165
1 libobjc.A.dylib objc_exception_throw + 48
2 CoreFoundation -[NSOrderedSet objectsAtIndexes:] + 952
3 Foundation NSKeyValueWillChangeByOrderedToManyMutation + 568
4 Foundation NSKeyValueWillChange + 383
5 Foundation -[NSObject(NSKeyValueObserverNotification) willChange:valuesAtIndexes:forKey:] + 557
6 CoreData -[NSManagedObject(_NSInternalMethods) _excludeObject:fromPropertyWithKey:andIndex:] + 526
7 CoreData -[NSManagedObject(_NSInternalMethods) _maintainInverseRelationship:forProperty:oldDestination:newDestination:] + 254
8 CoreData -[NSManagedObject(_NSInternalMethods) _didChangeValue:forRelationship:named:withInverse:] + 567
9 Foundation NSKeyValueNotifyObserver + 347
10 Foundation NSKeyValueDidChange + 466
11 Foundation -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 118
12 CoreData -[NSManagedObject didChangeValueForKey:] + 135
13 CoreData -[NSManagedObject(_NSInternalMethods) _updateFromRefreshSnapshot:includingTransients:] + 758
14 CoreData -[NSManagedObjectContext(_NestedContextSupport) _copyChildObject:toParentObject:fromChildContext:] + 567
15 CoreData -[NSManagedObjectContext(_NestedContextSupport) _parentProcessSaveRequest:inContext:error:] + 1103
16 CoreData __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 364
17 CoreData internalBlockToNSManagedObjectContextPerform + 84
18 libdispatch.dylib _dispatch_client_callout + 8
19 libdispatch.dylib _dispatch_barrier_sync_f_slow_invoke + 284
20 libdispatch.dylib _dispatch_client_callout + 8
21 libdispatch.dylib _dispatch_main_queue_callback_4CF + 1738
22 CoreFoundation __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
23 CoreFoundation __CFRunLoopRun + 2073
24 CoreFoundation CFRunLoopRunSpecific + 488
25 GraphicsServices GSEventRunModal + 161
26 UIKit UIApplicationMain + 171
27 My app main + 111
28 libdyld.dylib
Any suggestions? I can’t quite figure this one out.
Just don't. Add a different method which returns a filtered copy of the original relationship. Also, for the implementation just iterate the collection and add the items you want to keep to an entirely new collection, don't copy and filter.
The crash is because the array you're filtering is actually backed by the datastore, so as you filter it it's changing the contents you're iterating with the filter, and it's screwing up the original relationship.

Crash when Fetched Results Controller updates table after saving a background MOC

I have a tableView hooked up to a FRC (Fetched Results Controller) , I also have two contexts , namely backgroundContext initialised in a private queue and a mainContext initialised on the main queue. I also have setup the didSaveNotification to pass the objects from one context to another. When ever i save some data in the backgroundContext it saves successfully and FRC updates ,but if i repeat the process again the app crashes with an error
'The left hand side for an ALL or ANY operator must be either an
NSArray or an NSSet.'
The saving is done through a form which is presented modally. The same viewController works fine if presented in other viewControllers . but crashes only in one particular one. But again other that presenting the Form no other extra stuff is being done.
Here's my entire crash report.
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'The left hand side for an ALL
or ANY operator must be either an NSArray or an NSSet.'
* First throw call stack: ( 0 CoreFoundation 0x0000000103575495 exceptionPreprocess + 165 1 libobjc.A.dylib
0x0000000102fbb99e objc_exception_throw + 43 2 Foundation
0x00000001003c706b -[NSPredicateOperator
performOperationUsingObject:andObject:] + 826 3 Foundation
0x00000001003c6c1e -[NSComparisonPredicate
evaluateWithObject:substitutionVariables:] + 314 4 Foundation
0x00000001003c6ae2 -[NSPredicate evaluateWithObject:] + 19 5
CoreData 0x0000000102d61d06
-[NSFetchedResultsController(PrivateMethods) _objectInResults:] + 102 6 CoreData 0x0000000102d630f7
-[NSFetchedResultsController(PrivateMethods) _preprocessUpdatedObjects:insertsInfo:deletesInfo:updatesInfo:sectionsWithDeletes:newSectionNames:treatAsRefreshes:]
+ 519 7 CoreData 0x0000000102d642d5 -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 1781 8 CoreFoundation 0x00000001035cad9c
__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 12 9 CoreFoundation 0x000000010352d51d
_CFXNotificationPost + 2381 10 Foundation 0x000000010035b7fa -[NSNotificationCenter
postNotificationName:object:userInfo:] + 68 11 CoreData
0x0000000102c9048a
-[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 74 12 CoreData 0x0000000102d16c8b
-[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:]
+ 331 13 CoreData 0x0000000102c8c9cc -[NSManagedObjectContext(_NSInternalChangeProcessing) _postRefreshedObjectsNotificationAndClearList] + 108 14 CoreData 0x0000000102c8c5e4
-[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 2804 15 CoreData 0x0000000102c663cb _performRunLoopAction + 267 16 CoreFoundation
0x0000000103540dc7
CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23 17 CoreFoundation 0x0000000103540d37
__CFRunLoopDoObservers + 391 18 CoreFoundation 0x0000000103520522 __CFRunLoopRun + 946 19 CoreFoundation
0x000000010351fd83 CFRunLoopRunSpecific + 467 20 GraphicsServices
0x00000001037ecf04 GSEventRunModal + 161 21 UIKit
0x00000001011bde33 UIApplicationMain + 1010 22 Expense_Manager
0x0000000100001d13 main + 115 23 libdyld.dylib
0x000000010420c7e1 start + 0 ) libc++abi.dylib: terminating with
uncaught exception of type NSException
Thanks in advance.
Okay i actually found out why this was happening a few days ago. There was a notification being fired off when the form dismissed which reloaded a tableView from another viewController hooked up to an FRC sharing the same context. Once I removed itself as an observer in viewDidDisappear it did not crash. :) I hope this helps incase someone is facing the same problem.

Resources