The reason existingObjectWithID:error:
returns nil
here is simply that the object doesn't exist for that context, because it's a temporary object from a different context.
If you create an object in one managed object context but don't save it, it only exists in that context. No other managed object context has any way of knowing about it. It's not in memory for them, and since it's not in the persistent store, there's no way for them to find it. When you call existingObjectWithID:error:
, the context checks what it has in memory and, if necessary, the persistent store. For an unsaved object from a different context, neither check will find anything.
Once you save changes, the object is written to the persistent store file, and then other contexts can find it. At that point, existingObjectWithID:error:
would return non-nil
for the ID.
Calling objectWithID:
will return an object, but not one that you can use. That method assumes that you've provided a valid object ID, so it doesn't check the persistent store. If the object exists, its data will be faulted in normally. If it doesn't, you'll get an exception. This method is useful when you know the object exists and want faster response. In your case the object doesn't exist, so calling this method gives you a time bomb that will blow up your app.