Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I Have to Manually Set a Core Data Object's Inverse Relationship in Code on the iPhone

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();
    }

}
like image 283
iHorse Avatar asked Jul 13 '11 20:07

iHorse


2 Answers

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.

like image 72
TechZen Avatar answered Sep 21 '22 05:09

TechZen


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

like image 33
iHorse Avatar answered Sep 22 '22 05:09

iHorse