Simplify your models with SMModelObject
Check out SMModelObject on Github.
For almost every app we’ve made, I find myself writing “model classes” to store structured data and logic. For instance, when you search for a book in the Barnes & Noble app, we fetch book results from an XML-based API and parse the XML into Cocoa objects that get passed around to our Controllers and Views.
Pretty standard stuff. Now, one way to represent this data in memory would be to use anonymous NSArray+NSDictionary structures, like so:
I don’t know about you, but I cringe when I look at that
code. So verbose, hard to read, no refactoring, no code
completion; but most importantly, no type safety. I might write
@"pric"
by mistake somewhere else and waste an hour
debugging.
So let’s write a “model class” to store Books in a typesafe way.
Again, very standard. Now we can create these typesafe objects and access their properties directly:
So, ahhh, much better.
But, man, that Book class seems like a lot of wasteful typing.
Every property has to be written up to four times: declare
instance var, write property, write @synthesize
, and
release in -dealloc
if necessary.
Seems manageable until you start dealing with real-life objects. In the Barnes & Noble app, Books have twenty-one properties. And Book is just one of a couple dozen model classes in the app. Sigh.
Now, it turns out that ObjC has gotten better over the years, and
as of the latest iOS SDK (4.2), LLVM+Clang can create your
instance variables automatically and now write your
@synthesize
for you as well. This is really nice!
Leveraging this feature, our Book class now looks like:
Which is great, but we can do even better. Objective-C makes it easy to introspect classes at runtime, so we’ve created a simple base class called SMModelObject.
Using runtime introspection, SMModelObject
can do
lots of great stuff for free:
- Automatic release of properties in
-dealloc
- Automatic implementation of
NSCopying
-
Automatic implementation of
NSCoding
so you can archive/unarchive your model objects to disk for state saving or for the clipboard -
Automatic
-isEqual
and-hash
implementation to compare model objects by value
Now our Book class looks like this:
SMModelObject
even overrides
-description
to print nicely-indented model object
hierarchies for easy debugging.
Kickass.
EDIT 3/26/2011: This article used to demonstrate a feature of the Clang compiler that was experimental at the time: automatically writing @synthesize statements for you. It was awesome, but Apple decided it wasn’t finished and so the official Xcode release doesn’t contain it. I’ll update this article again once it’s released.
EDIT 8/29/2012: Xcode 4.4 now includes the LLVM 4.0 compiler which automatically @synthesizes properties as promised! It’s pretty much awesome. I’ve updated the article to demonstrate the niceness again.
This all started when
André Pang wrote an
amazing model base class called
RMModelObject
a few years back that is incredibly sophisticated and provides
these same great features on the legacy ObjC runtime.
RMModelObject
was the inspiration for my class, which
was much easier to write since ObjC 2.0 does all the heavy
lifting.
We’ve historically used RMModelObject for all our model classes, so I must give full credit to André for this wonderful concept, and for saving me many extra hours of typing over the years.