0

I have the following simple relationship:

Parent has many Children (ordered)
Child belongs to Parent.

And I get a strange behaviour:

// In of my classes, I keep a reference to a child.
@interface Foo ()
{
    Child *_child;
}

// Somewhere in my code I create a child and a parent and associate them.
Child *c = (Child *)[NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:moc];
Parent *p = (Parent *)[NSEntityDescription insertNewObjectForEntityForName:@"Parent" inManagedObjectContext:moc];
[p addChildrenObject:c];
c.parent = p;
_child = c;

// Then somewhere else I do:
Parent *parent = _child.parent; // It works fine
NSOrderedSet *children = parent.children; // Same, I do see the children
int idx = [children indexOfObject:_child]; // idx is NSNotFound!!

What I can see is children contains childs with normal IDs, whereas my _child reference still has a temporary ID.

I am using the same context everywhere.

I guess I am doing something wrong with my references, but I am not sure what it is?

PJC
  • 987
  • 7
  • 18
  • Post your definition of Child. But Tiago is pretty much on the money I think. – occulus Nov 05 '13 at 14:09
  • Do you really have an "ordered relationship" and that is your actual code? Because I would expect that `[p addChildrenObject:c]` crashes, due to a Core Data bug described e.g. here: http://stackoverflow.com/questions/7385439/exception-thrown-in-nsorderedset-generated-accessors. – Martin R Nov 05 '13 at 14:40
  • @MartinR I do yes. I use this to make it work: https://github.com/CFKevinRef/KCOrderedAccessorFix It is very useful. – PJC Nov 05 '13 at 14:50
  • OK (perhaps add that information to the question, perhaps it is relevant). But I cannot reproduce your problem. Your above code works for me (using that KCOrderedAccessorFix) and `idx = 0` as expected. – Martin R Nov 05 '13 at 15:01
  • @MartinR Thanks for trying. It does work for me "most of the time" as well. But from time to time it will break. I believe it happens when the child ID is updated from temporary to permanent. Somehow Core Data does something that breaks the reference. – PJC Nov 05 '13 at 15:08

1 Answers1

0

In response to your last comment:

I believe it happens when the child ID is updated from temporary to permanent. Somehow Core Data does something that breaks the reference.

You are almost certainly correct. Here is an exert from the documentation about objectId:

Important: If the receiver has not yet been saved, the object ID is a temporary value that will change when the object is saved.

That being said, if you have some other unique property on the child you could do use KVO to run comparisons:

int idx = [[children valueForKey:@"uniqueProperty"] indexOfObject:_child.uniqueProperty];
Firo
  • 14,960
  • 3
  • 50
  • 73
  • Thanks. That's the thing though: there is no unique property in this model besides the ID itself. I guess I will have to change my design. – PJC Nov 05 '13 at 15:28
  • @PJC hmm, could you just do a save after you insert the objects and save that into your ivar? – Firo Nov 05 '13 at 15:32
  • @PJC actually try doing this: `refreshObject:mergeChanges:` on your object before you use `indexOfObject:`. I bet that will do it! – Firo Nov 05 '13 at 15:33
  • It did not work, no. I think Core Data did not find the corresponding record in the context. I ended up creating a UUID for this specific object and purpose. – PJC Nov 05 '13 at 22:55