Style For Cocoa Programmers
Volume Number: 21 (2005)
Issue Number: 7
Column Tag: Programming
Tips From Big Nerd Ranch
Style For Cocoa Programmers
by Aaron Hillegass, Chris Campbell, Marquis Logan
As developers and teachers, we spend a lot of time dealing with issues of style. Not just because we like
to look cool for the ladies; code that is written by a stylish programmer is easier to read and maintain. The
Cocoa community has developed idioms, and if you want other developers to be able to easily comprehend your
code, you should follow those idioms.
Issue #1: Whitespace
Here is a perfect setter method that explicitly invokes key-value observing:
- (void)setBorderColor:(Color *)c
{
if (c == borderColor) {
return;
}
[self willChangeValueForKey:@"borderColor"];
[c retain];
[borderColor release];
borderColor = c;
[self didChangeValueForKey:@"borderColor"];
}
Notice the use of whitespace. In particular, we do not put spaces after colons. We do not put spaces
after the type of the parameter (That is, "(Dog *)").
Also, notice that there are no comments. What this method does is self-evident from its name. Too many
comments can be just as annoying as too few.
Issue #2: Grouping Methods
In an implementation file, methods should be grouped in a meaningful manner. In particular, we try to
follow this order:
Class methods
Initializers and dealloc
copyWithZone:
isEqual:
hash
initWithCoder: and encodeWithCoder:
action methods
other methods (subgroup meaningfully)
delegate methods
accessor methods (in setter/getter pairs)
Use #pragma mark to show where a group of methods begins. The information will show up in the popup in
Xcode. For example, you might insert these lines:
#pragma mark Coding methods
#pragma mark Color metrics
#pragma mark Accessors
So that your Xcode popup would look like this:
Figure 1.
Issue #3: Naming methods
If you have a method that returns the brightness of a border, it should be named thusly:
- (float)borderBrightness;
We do not put articles on method names:
- (float)theBorderBrightness;
We do not prefix methods with get-:
- (float)getBorderBrightness;
The exception to this rule is if the method is pass-by-reference:
float r, g, b;
[borderColor getRed :&r
blue :&b
green :&g
alpha :NULL];
If a method takes one argument and is prefixed with set-, it should be an accessor. In particular, an
action method should never be prefixed with set-.
Issue #4: What Goes In The .h File
The primary purpose of your .h file is so that I can create an instance of your class and send messages to
it. Many people put too much information in their .h files. Don't declare any of the following in the .h
file:
1) Delegate methods.
2) Private methods.
3) Any methods in a protocol that you conform to. For example, if you have:
@interface Chowder : NSObject <NSCopying>
There is no reason to declare copyWithZone: in your .h file.
4) Any inherited or overridden methods.
Issue #5: Declaring Local Variables
Declare temporary variable in a "just-in-time" manner. When I'm reading your code, I don't want to have
to scroll to the beginning of the method to figure out the type of a local variable. Move the declaration as
close to the first use as possible.
The Analysis and Design Workshop
In a short column, it is easy to discuss small issues like code formatting and variable naming. For larger
and deeper issues, we need a much bigger forum. At the ranch in August, we are hosting an "Analysis and
Design Workshop." John Graziano, who had a major part in the design of Xcode, WebObjects Builder, and many of
the animation systems at Pixar, will lecture and guide hands-on exercises that teach good design practices.
He is going to focus on creating designs that make change and maintenance easy. John started developing these
ideas at NeXT, and they have received much acclaim within NeXT, Apple, and Pixar. Bring your specifications,
and go home with the beginnings of a really good design for your app. The workshop is August 15 - 19 in
Atlanta. We hope to see you there.
Aaron Hillegass, Chris Campbell, Marquis Logan