My Objective-C Style Guide

28 June 2011 My Objective-C Style Guide

Reading Marcus Zarra's own style guide, I thought I'd write a post outlining my own conventions.

I don't agree with all of Marcus' guidelines; some I positively disagree with. I'll try and outline some of those below and my reasons why.

I try not to be religious or zealous when it comes to coding conventions; the most important thing, when working on a team, is to establish the guidelines up front and stick to them.

Consistency trumps personal opinions. If that means having to stick to conventions that you wouldn't normally in your own code when working on different teams, then so be it. The more zealous you are about your own personal style, the harder you will find it to adapt.

If you are new to Objective-C or Cocoa/CocoaTouch and want some general guidance on good coding conventions, it's well worth reading Apple's suggestions. Google also have a style guide.

Here's my guidelines; if there is something I do not cover, it either means I'm yet to form a firm opinion or simply do not care either way:

Dot notation

Dot notation should always be used for properties and should also be used for accessor/mutator-like methods that aren't declared properties. Generally speaking, dot notation should only be used for reading an object's state (the exposure of which should be kept to a minimum) or setting it directly. Objects that perform a commands or have side-effects should never be called using dot-notation.

White space

Two spaces, no tabs. There should be no extraneous white space at the end of a line. Apple's templates tend to use four spaces and I have occasionally considered switching but due to me using two spaces in all of my Ruby code, I tend to stick with two spaces for consistency.

Method braces always appear on a line of their own. Other braces (if/else/switch/while etc.) open on the same line as the statement but close on a new line.

There should be no spaces between parentheses and their contents.

Variables

Variables should be named as descriptively as possible. The only time a single letter variable is considered acceptable is in for() loops. Asterisks indicating pointers belong with the variable, not the type.

Direct instance variable access should be avoided where possible, except for in init and dealloc methods. Consider declaring private properties in a class continuation in the implementation file to encapsulate memory management.

When releasing variables in dealloc, it is not necessary to nil them out as well. Properties should not be used in dealloc or init; the variables should be released directly. dealloc should only be used to release variables, nil delegates or anything else related to releasing memory.

When ARC is released and production ready, all arguments regarding best practice when it comes to variables, nilling them and what to call in dealloc become moot. Move along and use ARC as soon as you can.

Method signatures

The only spaces that should appear in a method signature should be after the scope indicator and in any pointer variables (see above).

Naming

Apple naming conventions should be adhered to wherever possible, especially those related to memory management rules (init, new, alloc, copy etc.). Long, descriptive methods names are good. Class name prefixes should always be used when writing shared/open-source library code.

Code structure

Header files should only ever declare the public interface. Private/protected methods should be contained in class continuations inside the implementation file.

Within an implementation, methods should be logically grouped using #pragma marks, including protocol implementations. @synthesize statements should appear at the top of the class, followed by any init methods, then the dealloc method. @dynamic properties should be explicitly declared.

Protocols should be declared in their own files.

Project organisation

All classes should be kept within a "Classes" folder on the file system. Test classes should be kept in a folder called "Tests", or "Specs". Resources and nibs should be kept in a "Resources" folder. Frameworks should be kept in a "Frameworks folder" and external projects and repositories (e.g. git submodules) should be kept in an "External" folder.

Further organisation of classes should be done using Xcode groups. Trying to keep Xcode groups in sync with actual file system directories is not worth the hassle.

The only files that should appear in the root of a project directory are the Xcode project file, Info.plist and any prefix header. Occasionally, other files may appear (README, LICENSE files in open-source projects).

Comments

Comments should be used sparingly. When they are used, they should be used to explain why a particular piece of code does something.

If you've chosen a particular algorithm or have made some kind of non-obvious performance optimization, comments are a great way to explain why. If you find yourself writing comments that act as a narrator to your code, explaining what is happening, stop and think about how you could refactor your code to make it make it self-documenting.

Any comments that are used, must be kept up-to-date or deleted.

The only exception to the above commenting rules are those used to generate documentation.

Postscript

Like Marcus' guide, this should be considered a living document. I will try and keep it updated and will consider changing a particular practice if I feel there is a good reason to do so. If you want to discuss this with me, Twitter is the place to do it.