My app uses Core Data (with some help of Magical Record) and is rather heavily multithreaded using NSOperation
.
Of course I am very careful to only pass around NSManagedObjectID
between threads/operations.
Now, to get back to the corresponding managed object in an operation, I use -existingObjectWithID:error:
thus:
Collection *owner = (Collection *)[localContext existingObjectWithID:self.containerId error:&error];
But what I get back is nil and error
says this is an error #13300: NSManagedObjectReferentialIntegrityError
.
Here is what the documentation says about this error:
NSManagedObjectReferentialIntegrityError
Error code to denote an attempt to fire a fault pointing to an object that does not exist.
The store is accessible, but the object corresponding to the fault cannot be found.
Which is not true in my case: that object exists. Indeed, If I iterate through all instances of that Collection
entity with an NSFetchRequest
, I find it among them, and its NSManagedObjectID
is exactly the one I passed to -existingObjectWithID:error:
.
Moreover, if I use -objectWithID:
instead, I get a correct object back just fine.
So there is something I'm missing. Here are a few additional observations/questions:
So maybe I am missing something regarding what existingObjectWithID:error:
does? The documentation says:
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.
[...]
Unlike objectWithID:, this method never returns a fault.
This doesn't help my issue. I don't mind getting my object fully faulted, and not a fault. In fact, any fault within it will fire on the next code line when I access the object properties.
NSManagedObjectReferentialIntegrityError
?Thanks for any enlightenment.
The problem is that NSManagedObjectID
you pass is temporary. You can check it by calling NSManagedObjectID
's isTemporaryID
method. From docs:
Returns a Boolean value that indicates whether the receiver is temporary.
Most object IDs return NO. New objects inserted into a managed object context are assigned a temporary ID which is replaced with a permanent one once the object gets saved to a persistent store.
You should first save your changes to persistent store, only then get a permanent ID to pass to other context.