views:

62

answers:

4

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?

A: 

Because if you use CoreData, it's possible that you have the object's properties tied to some UI elements (like labels or input fields). KVC approch uses KVO and notifications to tell the UI which of object's properties have changed so that UI could update the elements. The dot notation (or properties) skip the notification posting hence even though you changed the attribute your UI shows the old state of the object.

Eimantas
This is incorrect. Want to delete it?
mustISignUp
can you elaborate?
Eimantas
Use of . notation does in fact trigger observers.
Kendall Helmstetter Gelner
A: 

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.

mustISignUp
You can add a property `favouriteRestaurant` in `@interface` to shut up the compiler, if you want.
Yuji
You mean if you add a custom class for your entity?
mustISignUp
+2  A: 

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).

Kendall Helmstetter Gelner
+1  A: 

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.

Marcus S. Zarra