Reputation: 14605
My iOS app uses core data via multiple threads. I am getting some crash reports with the following message: "'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x1e07a9b0 ''
I understand what is causing this problem - that the object was deleted but another thread is trying to access it. I am working to solve the problem but I want to add a check in the background thread to see if the object will fault in this manner.
My code at the moment relates to myObject.myValue
. Is it possible to do some check, such as:
if (!myObject.myValue) {
return;
}
... so that it will get out of the method before doing anything that could cause such a crash? Or will simply calling myObject.myValue
, even to see if it's null, cause such an exception to be thrown?
Upvotes: 8
Views: 12248
Reputation: 736
You could give a try to use :
shouldDeleteInaccessibleFaults
property on managed object context. As this article says it should change the behaviour of faulting already deleted object.
https://cocoacasts.com/what-are-core-data-query-generations/
Edit: Since iOS 9 (when it was added) this property default value is YES.
Upvotes: 0
Reputation: 149
You can check the NSManagedContext is existed when you use the NSManagedObject. like this:
if (obj.managedObjectContext)
{
//do things
}
Upvotes: 3
Reputation: 3017
You can check [myObject isFault]
where myObject
is a NSManagedObject
instance
Upvotes: 0
Reputation: 46713
You should verify that the object exists before accessing it's variables if you're having issues where the object may be deleted on another thread.
Two methods:
NSManagedObjectContextObjectsDidChangeNotification
notification and then parsing the userInfo
on that notification to see which object was deleted.Example:
// Cache and pass the object's ID off to another thread to do work on
// You can just store it as a property on the class
@try {
NSManagedObject *theObject = [managedObjectContext objectWithID:self.theObjectID];
// do stuff with object
}
@catch (NSException * e) {
// An entity with that object ID could not be found (maybe they were deleted)
NSLog(@"Error finding object: %@: %@", [e name], [e reason]);
}
Upvotes: 5
Reputation: 69047
You could try and use existingObjectWithID:error:
:
Returns the object for the specified ID.
- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error
Discussion
If there is a managed object with the given ID already registered in the context, that object is returned directly; otherwise the corresponding object is faulted into the context.
This method might perform I/O if the data is uncached.
Unlike objectWithID:, this method never returns a fault.
You could dO:
if ([myMOC existingObjectWithID:myObject.objectID error:&error])
...
Upvotes: 19