existingObjectWithID:error: returns nil, but objectWithID: returns an actual usable object
Asked Answered
A

1

9

My understanding from the documentation and from this answer is that if the data exists, NSManagedObjectContext's existingObjectWithID:error: and objectWithID: methods should return the same object, but when the data doesn't exist, existingObjectWithID:error: will return nil while objectWithID: will return an object that has faults instead of data.

What I'm seeing in an application is an instance where (after creating the object on a background thread within a child managed object context and saving, then going to the main thread, saving, and bringing the object ID from the child context to the parent object context), existingObjectWithID:error: returns nil, but objectWithID: returns an actual usable object with valid data, not faults.

Is my understanding of the two methods incorrect? Am I doing something wrong?

(I want the returns-nil-when-there's-no-data behavior of existingObjectWithID:error:, but the inability to get the data for newly-created objects is problematic.)


edit: I suppose I could use objectWithID:, then immediately test accessing a property of the returned object within a try-catch block, catching the thrown exception, and replacing the faked object with nil (as is done here), but try-catch is expensive in Objective-C and this seems like a really bad idea.

Amplify answered 19/9, 2012 at 22:2 Comment(4)
Are you performing a mergeChangesFromContextDidSaveNotification: when the child context saves and posts the NSManagedObjectContextDidSaveNotification notification?Reyna
@dtrotzjr: Yes, I am.Amplify
Can you please show your code? There are so many things you can do wrong. Without seeing your actual code this is a guessing game. One possibility is that you are saving by using performBlock: and that you use the object id in the parent context before the performBlock: was executed. Your idea with try catch is bad. Don't try it. Solve the underlying problem instead of fixing the symptom with try catch.Brickwork
When you get nil from existingObjectWithID:error:, what's the value of your error parameter?Previse
L
3

The problem could be in temporary object IDs. Object ID is not permanent until it is saved to the store. So the question is when do you get the object ID from a managed object in child context: before you save the parent or after.

If you do this before you save the parent (which in turn, if parent is configured with persistent store coordinator and not with another parent, results in saving to the store), then you probably get temporary object ID. And for some reasons that are not disclosed to us by Apple one of the methods that return managed objects from object ID works, but the other doesn’t.

Longinus answered 20/12, 2013 at 11:44 Comment(1)
I was pulling my hair out.Determined

© 2022 - 2024 — McMap. All rights reserved.