davetron5000
davetron5000

Reputation: 24841

Accessing NSManagedObject fields with KVC/valueForKey vs properties - which is better?

Writing my first app with CoreData. The book I'm using to guide me has code like this:

// 'Person' is my managed object class
Person *newPerson = [NSEntityDescription
  insertNewObjectForEntityForName:@"Person"
  inManagedObjectContext:self.managedObjectContext];

[newPerson setValue:nameField.text forKey:@"name"];

The book says that using the property style, e.g.

newPerson.name = nameField.text;

also works, but that "it is very common to see Core Data code use the KVC Approach"

To me, I can't see one reason to use the KVC approach; magic strings just beg for runtime errors and it's a lot more typing.

That being said, I'd like to learn my habits now regarding the "iPhone Way" of doing things.

Is there a difference in these approaches and, if most people use the first, KVC, approach…why?

Upvotes: 4

Views: 2496

Answers (3)

Marcus S. Zarra
Marcus S. Zarra

Reputation: 46718

Properties will result in a fractional performance increase over direct KVC usage. However KVC does have its uses especially when working with a keyPath as opposed to just a key.

KVC is also useful when you are discovering or dynamically accessing values on an object.

For every day use, Kendall is definitely right, use mogenerator and utilize properties. Easier to code, easier to maintain, etc. However KVC definitely has its place and is extremely useful.

Upvotes: 1

Most people do not use the KVC approach I have seen; I do not, for the reasons you describe.

To save your sanity, use Mogenerator to build your accessors:

http://rentzsch.github.com/mogenerator/

It's a command line tool that generates proxy objects that you can use to fetch CoreData objects, with some convenience methods - but even better, some category overlays that you can add your own methods to that will not be destroyed when you re-generate classes from your data model.

XCode can also generate data objects from your model but the classes are more simple (just accessors), and mogenerator is I think easier to use repeatedly (which is important since you will tend to change the model a lot over time). Perhaps the next XCode will be better in that regard.

I usually generate all data model classes into a subdirectory under Classes called "DataObjects" - then you can just re-add that whole directory every time you regenerate classes from the data model that leads to new classes being created (when you have new entities). A sample command line run looks like:

 mogenerator -m ../MyProject.xcdatamodeld/MyProject-v1.xcdatamodel

which will generate classes into the current directory from the given data model (in that case I have a versioned model with just the first version).

Upvotes: 3

hooleyhoop
hooleyhoop

Reputation: 9198

name is a property of NSEntityDescription, so newPerson.name is fine.

But when you add a custom property to your custom entity, it is only known about at runtime - so newPerson.favouriteRestaurant will trigger a compile time warning, even though it's fine.

This is annoying.

One way to get rid of it is to use

[newPerson setValue:@"Crazy Maria's" forKey:@"favouriteRestaurant"]

This can be a useful way to stop the compiler nagging in several other scenarios when you are gong to use runtime magic.

Upvotes: 0

Related Questions