views:

170

answers:

2

In an iPhone app, I need to customize the look of a UINavigationController class. For instance, make the bar and font size bigger. My client really needs that, and bigger buttons aswell.

So, instead of writing the class from scratch, I decided to subclass UINavigationController. My question is, can I customize any method or attribute's default value? Is there any restriction while subclassing a class?

+2  A: 

No, feel free to go nuts. Many Cocoa classes are not as subclassing-friendly as others (especially those that are meant to rely more on delegate control) and may not expose the functionality you need, but you can feel free to subclass any method that's not private (begins with a _ prefix). You could even subclass those if you really wanted to, although on the iPhone chances are Apple would reject your app.

Marc Charbonneau
+1  A: 

It depends what you mean by "restriction". The runtime will not prevent you from subclassing whatever you like, but there are a few gotchas. (Although your answer is specifically about UINavigationController, the title and concept are bigger, so I'll address the bigger issues.)

  1. There may be variables in the parent class which are marked @private and child classes cannot access, versus the default of @protected, which are accessible.
  2. Some classes are designed for subclassing (and most AppKit and UIKit classes are) but for others it is extremely unwise. For example, key foundation classes like NSString, NSMutableArray, etc. are actually class clusters, meaning an instance of the class may actually be one of several private classes.
  3. Classes that are designed for subclassing will usually document the key methods which must be overridden. For example, NSDictionary and NSMutableDictionary describe a few "primitive" methods which every other method calls down to, so overriding 2 or 3 in each case is sufficient to change the behavior without re-implementing everything else.
  4. Be extremely careful to call the parent class' implementation of your overridden method if and when it is necessary. This can be especially important in UI classes, which often have more complex behavior than simple get/set data classes.

In this case, you're exactly right to not write the class from scratch — that would be a Bad Idea™. If you want to change the default value of an attribute (field?), you can set the desired value in an initializer after calling the parent's initializer. However, if you do this, make sure you're not hosing something in the parent class, and always test thoroughly.

Apple has reserved methods that start with "_" for their own use, so I'd echo Marc's caution to not touch those at all. Everything else is fair game, within reason of course. :-)

Quinn Taylor