I’m just getting started with CoreData, and I’ve been excited about about its nice graphical environment to define your model.
CoreData’s approach to ORM is somewhat different than other tools, such as Hibernate, because it takes advantage of Objective-C’s dynamic nature, and avoids some of the clutter problems you experience with more statically typed languages. Instead of providing mapping information for classes that are defined elsewhere, all modeled objects are instances of NSManagedObject and the system customizes the accessors on the created objects based on the schema.
This is very nice when you are defining your model, and when you can use things like Cocoa Bindings to provide much of the system’s behavior based on state of the model, but when you need to start writing custom controller logic, it isn’t very readable to have everything going around as an NSManagedObject. You can use the dynamically generated properties on these objects, but you will get compiler warnings. Annoying.
You can certainly subclass NSManagedObject and tell the model to use your implementation. This is necessarily if you are going to provide custom behavior on the model objects above the simple data oriented behavior CoreData provides for you. Xcode will even generate source code for you from your data model.
While in the data model editor, do File, New File… and select Managed Object Class from the Cocoa category.
Choose the location where your files will be generated.
Select the model entities for which classes will be generated and click Finish.
The problem with this approach is that you are stuck manually keeping the model and the custom classes in sync. You can certainly regenerate, but if you have made any changes to the files, they will be overwritten.
One alternative to this manual update process is a tool, mogenerator, that will automatically generate custom classes for you. It even goes so far as two generate two classes for each model object:
NSManagedObject <— GenClassA <— GenClassB (where <— represents inherits from). This allows you to modify the code in GenClassB and leave GenClassA alone, which stores the core information from the model. This way you can regenerate GenClassA as needed, without overwriting your custom behavior in GenClassB. PyrusMalus has an introduction on how to get started with mogenerator, Important Shock has a discussion about the approach used by the tool, and Cocoa & Medicine has a description of how to run mogerator from within Xcode using Apple Script.
There is some dissension about if the method of generating custom classes is a good thing. On this thread on CocoaBuilder Ben (who appears to be from Apple according to LinkedIn) seems to be against the idea, though I his main objection is to the idea that the custom accessors generated by NSManagedObject are slower than those statically generated by mogenerator.
One of Apples recommended approaches to avoid compiler warnings is to created categories for NSManagedObject so that the compiler accepts that the accessors you are using are actually there. Xcode provides the ability to copy the attribute declarations for use in these categories (or in custom classes), but to cover everything, you need to copy two separate sets of declarations and paste them into the code. You could use the Xcode custom class generation to get the signatures you need, but there is a still a bit of manual work in the process.
In my opinion, Apple needs to work more to help developers with this problem. I like the approach taken by mogenerator, and I would like to see that same regenerative ability in the built-in Xcode tools, using the 2-class generation-gap design pattern to allow you to make changes to the generated classes without having the changes overwritten next time you re-generate.