I’m on a project doing an iPhone application. We had a Cocoa consultant come in for a few weeks. He showed me an interesting idiom of Cocoa, dealing with interfaces, but there was a difficult language barrier between us, and he wasn’t really able to explain why this was done or where it was documented so I could learn more on my own. I went into monkey see mode, and just used the style he prefers. But it’s been bugging the hell out of me that I don’t know more about the history of this style. It’s certainly NOT an informal protocol. Sure enough, looking at some of the Cocoa API headers, I sometimes see the style he asserted was the ‘Cocoa’ way. Here’s an example (note accessors, mutators, etc., each have their own interface declaration without the funny braces):
@interface AViewController : UIViewController <UITextViewDelegate> { @public UITableView *tableView; @private NSUInteger someIndex; } @property (nonatomic, retain) ... @end @interface AViewController (AViewControllerCreation) - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil withController:(id)controller; @end @interface AViewController (AViewControllerMutator) - (void) doSomeSettingStuff; @end @interface AViewController (AViewControllerAccessor) - (NSString *)doSomeAccessorStuff; @end @interface AViewController (AViewControllerAction) - (IBAction)cancel:(id)sender; @end @interface AViewController (AViewControllerTableViewDelegate) <UITableViewDelegate, UITableViewDataSource> @end
You can see this style of setting up the interface in NSButton, NSControl, etc. Interestingly, corresponding classes like UIButton, UIControl DON’T use this idiom. Hmm, these probably came after as I assume UIKit was done after AppKit. So is this idiom ‘old hat’? Also, is there any reason for it other then style? Is it good style? Bad? Any docs that go over this? Thanks all.
These are what’s known in Objective-C as ‘categories’. Categories make it possible to have multiple @interface and @implementation blocks for the same class. This works even to the extent that you can add methods on classes in the standard Apple frameworks, e.g. adding a category on NSString to add new methods to it. Categories can add methods but not instance variables, so in your example the first @interface is the core class declaration and all of the others are categories on the AViewController class.
It’s not ‘old hat’ by any means but your example takes the use of categories to a rather bizarre extreme. Categories make sense wherever it makes logical sense to break up a class’s implementation into multiple blocks, for example if the class has a bunch of methods that logically fall into two or more groups. They’re also sometimes used to declare pseudo-private methods by putting a category @interface named ‘private’ in the same file as the @implementation. ObjC’s dynamic dispatch means there’s no such thing as a private method but this approach avoids publishing the names of methods you’d prefer people not to use.
The example above is not actually wrong but it’s kind of ridiculous. It suggests that the contractor got the idea that every new method should always have its own category for some reason, which is just not true.