7

I am new to core data so please excuse me if I get some of the terms wrong.

I have several objects in my xcdatamodel file. They are all inter connected with relationships and inverse relationships. If I connect two of these objects with the following code the inverse relationship is not set.

[managedObj1 setValue: managedObj2 forKey:@"relatiohipName"]; 

I seem to have to manually set the inverse relationship myself with the following code

[managedObj1 setValue: managedObj2 forKey:@"relatiohipName"];
[managedObj2 setValue: managedObj1 forKey:@"inverseRelatiohipName"];

This seems wrong to me but its the only way I can seem to get the mechanism to work. I have looked at the sqlite DB after running the first block of code and the inverse relationship is not filled in but if I run the second code the relationship is there.

Also, it seems like once I create an object in Core Data I can't alter it after that. The dp remains the same. Once I exit the app and restart it I seem to lose all the relationships and attributes of the object. the resulting objects in my code have nothing but nil member variables.

EDIT:

The commented out stuff is the way it was done before and the uncommented stuff is how I'm doing it now with no luck.

Here is where I am creating the objects:

NSEntityDescription* mobileEntity = [NSEntityDescription entityForName:@"WebServiceAuthService_mobileAdvertisementVO" inManagedObjectContext:managedObjectContext];
WebServiceAuthService_mobileAdvertisementVO *newObject = [NSEntityDescription insertNewObjectForEntityForName:[mobileEntity name] inManagedObjectContext:managedObjectContext];
//WebServiceAuthService_mobileAdvertisementVO *newObject = [NSEntityDescription insertNewObjectForEntityForName:@"WebServiceAuthService_mobileAdvertisementVO" inManagedObjectContext:managedObjectContext];    

Here is where I am assigning one of the objects member variables:

[self setValue:newChild forKey:@"advertisement"];
            //self.advertisement = newChild;

Here is where I am saving the context:

NSError *error = nil;
if (managedObjectContext != nil) 
{
    if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) 
    {
        DLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

}
iHorse
  • 491
  • 1
  • 5
  • 14
  • 4
    Is your shift key broken? Writing without capitalization and punctuation is okay for short texting but it makes things hard to read in paragraphs. I've edited the post but in the future take the time to make your question easy for others to read. A lot of people will just give up trying to read such a lazily written question. – TechZen Jul 13 '11 at 23:00

2 Answers2

9

You have to set both sides of a relationship manually if you don't set the reciprocal relationship in the data model. If you do, then assigning one side of the relationship automatically assigns the other. That is one of the functions of the data model.

It sounds to me like you don't actually have your objects inserted into a NSManagedObjectContext object. The context is what "manages" the objects and does things like automatic relationship setting. The context is also what writes the objects to the persistent store.

TechZen
  • 64,370
  • 15
  • 118
  • 145
  • if they are not inserted you would think that they wouldn't show up in the sqlite DP. – iHorse Jul 13 '11 at 23:53
  • I'm not confident that they do, especially if they disappear after a restart. Looking directly at the SQL tells you very little about the actual operation of Core Data because the SQL isn't central to it's function. I would suggest posting the code where you create the managed objects and where you save the context. Clearly, something unusual is going on here. – TechZen Jul 14 '11 at 19:23
  • Check your build to make sure you haven't ended up with multiple data model files. If you were actually using a model file that did not have relationships when you thought you were using one that did, that would cause this issue. – TechZen Jul 14 '11 at 19:24
  • Isn't the SQL file where the persistent store saves and reads the data from? I agree that something odd is going on. I have an idea of where to look for a problem. If it turns out to be fruitless ill be back. – iHorse Jul 15 '11 at 16:34
  • The objects don't necessarily disappear. They are still in the SQL file I've looked. I get the correct number of parent objects back from the persistent store. Their member variables are just all nil. – iHorse Jul 15 '11 at 18:28
  • It is very hard to discern exactly what is going on just by looking at the SQL file because there is no one-to-one functional relationship between live objects in a context and the state of the SQL store at anyone time. Core Data isn't an SQL wrapper so the real data and logic aren't actually in the SQL store. Instead, Core Data stores bits and pieces of objects in SQL and then reassembles them. In my experience, using direct examination of the SQL to get facts to use as a deductive starting point is more likely to lead you astray. I would ignore the SQL except as a last option. – TechZen Jul 15 '11 at 19:03
  • OK. Well then what do you suggest then? I'm out of ideas. Everything I've read says what I am doing is correct and yet its not working. – iHorse Jul 15 '11 at 19:57
1

Important safety tip. If you subclass NSManagedObject DO NOT use @synthesize for your member variables. Use @dynamic instead.

iHorse
  • 491
  • 1
  • 5
  • 14
  • Hah! Never run into that before! Didn't even think of it. The synthesized accessors wouldn't have trigger the KVO of the context properly. – TechZen Jul 16 '11 at 01:31
  • I know. All the Core Data examples I've seen don't mention using @dynamic. The only way I found it was by having Xcode generate the class files from the xcdatamodel file. – iHorse Jul 18 '11 at 16:28