More iPhone Versus Java Differences
In my previous entries, I’ve discussed a few things that caught me off guard while learning iPhone development. In the last couple of weeks, I’ve picked up an Android device to dig into that platform a bit and probably will spend less time playing with iPhone development. Before I move too far away from iPhone, I wanted to wrap up the remaining differences I found interesting between the iPhone and Java platforms.
Run Loop Required for Networking
One of the earliest things I needed to do was build out the networking code for my Daap player. Initially, I was building this code as a standard Macintosh command-line application. I happily wrote code to set up a synchronous networking call using NSURL and NSURLConnection and then… nothing. Unlike Java, it was necessary to have a “run loop” executing. Had I done this test initially on the iPhone emulator, I would have never run across this since the iPhone has a run loop executing the application.
Subclassing and Class Clusters
In Java, it is not possible to add functionality to another class. The only real available option is to subclass the class of interest. In general, that works ok until you get a class like java.lang.String that isn’t mean to be subclassed, in which case you need to provide some kind of wrapper or utility class. My first attempt at adding some new functionality to NSMutableDictionary from the Foundation library was using a subclass. I was greeted at runtime by an error similar to:
2010-08-14 09:55:48.965 TestProject[1136:207] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSDictionary objectForKey:]: method only defined for abstract class. Define -[MyDictionarySubclass objectForKey:]!’
What the heck? It turns out that most of the collection classes in iPhone are implemented as class clusters. According to the Cocoa Fundamentals Guide class clusters
… group a number of private, concrete subclasses under a public, abstract superclass. The grouping of classes in this way simplifies the publicly visible architecture of an object-oriented framework without reducing its functional richness.
Had I really needed to subclass NSMutableDictionary, Matt Gallagher talks about how to create such a subclass. In my case, it turns out what I really needed was just an Objective-C category to add methods to NSMutableDictionary directly rather than subclassing the class. Categories remind me of similar functionality available in Smalltalk, allowing additional methods to be attached to classes. The class “shape” (instance variables) cannot be changed using categories, but new methods can be added which is very helpful for creating utility methods on a specific class rather than having to do it on a separate class. Looking around the documentation for the various frameworks in the system, it is amazing to see how many classes are extended using categories.
Although my Daap player is nowhere near complete, the project did offer me plenty of visibility into Objective-C and iPhone development. Objective-C and, in particular, the various libraries for iPhone development are incredibly powerful. While there were a few growing pains along the way, the transition to doing iPhone development was relatively straightforward and enjoyable.