small medium large xlarge

Back to: All Forums  Core Data
Generic-user-small
27 Mar 2010, 14:05
Scott Walter (2 posts)

All,

Although the books talks about 1-many relationships there really isn’t a full example. Page 56 talks about this but the code to create the many objects is assumed.

This is how I have implemented the code to add a 1-m relationship. Is this the best way? Am I doing something wrong?

Project *project = (Project *)[NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:managedObjectContext];
[project setName:@"Secret iPad Project"];
     
Task *task = (Task *)[NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:managedObjectContext];
task.description = @"deliver iPad";     
[task addTaskObject:task];
          
NSError *error;
if (![managedObjectContext save:&error]) {
  NSLog(@"ooops saving");
}
Avatarsmall_pragsmall
27 Mar 2010, 14:18
Marcus S. Zarra (284 posts)

There are several ways to add relationships to a 1-to-many. While what you have listed is one of them, there is a bug in it. Specifically you should be adding the task to the project not to the task:

[project addTaskObject:task];

You can also do the reverse:

[task setValue:project forKey:@"project"];

And you can get a reference to the set for the relationship and manipulate that:

NSMutableSet *tasks = [project mutableSetForKey:@"tasks"];
[tasks addObject:task];

One thing to note is that you do not need to do all of this casting that you are currently doing in your code. Objective-C is a very dynamic language and works equally well with the id as it does with these subclass definitions. So your code could just as easily be written:

id project = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:managedObjectContext];
[project setName:@"Secret iPad Project"];

id task = [NSEntityDescription insertNewObjectForEntityForName:@"Task" inManagedObjectContext:managedObjectContext];
[task setDesc:@"deliver iPad"];     
[task addTaskObject:task];

NSError *error;
if (![managedObjectContext save:&error]) {
  NSLog(@"ooops saving: %@", error);
}

In addition, I would recommend NOT naming any property “description” as that is a reserved word. You should have received a warning for that.

Lastly, when you get an error it is always helpful to print that error out to the console.

Generic-user-small
29 Mar 2010, 19:23
Scott Walter (2 posts)

Thanks for tips and heads up! I really liked the book, I was traveling and had time to read it from cover to cover. Just wish I had my iPad it would have made the read even better :-)

Avatarsmall_pragsmall
30 Mar 2010, 15:41
Marcus S. Zarra (284 posts)

btw even showing that I can miss a trick or two;

It was pointed out that since @[NSEntityDescription insert…]@ returns @id@, no casting is required at all. So you can do:

Project *project = [NSEntityDescription insert...]
[project setName:@"Secret iPad Project"];

Task *task = [NSEntityDescription insertNew..
You must be logged in to comment