Where Java has its Code Conventions for the Java Programming Language, Python its PEP 8 or C# its Coding Conventions, Objective-C doesn’t have any official guidelines for formatting sourcecodes. The official Coding Guidelines for Cocoa exists, but doesn’t cover code formatting or recent features of Objective-C like object literals.
However, there are guidelines that reference best practices, including about formatting that is missing in Apple’s official documentation. In this post, I will highlight topics that sounds particularly pertinents to me. It can be considered as my guidelines for Objective-C code formatting and will be formalized soon in a Github repository.
The iOS development team of The New York Times formalized its coding conventions in a Github repo. It is a great document, that covers a lot of syntax topics. I globally agree with this coding style. Here is a list of my favorite tips.
NYTimes suggest to always use the dot-notation syntax for accessing or mutating properties, but to use bracket notation in every other cases.
Always use braces when a conditional body could be written without, to prevent errors. It also help with reading.
The ternary operator might be used only when it increase code neatness or readability. It should never been used to evaluate multiple conditions, except refactored in multiple boolean variables.
If a method returns a
NSError instance by reference, the good practice is to switch on the returned value, not on the error variable (switching on the error variable value can cause false negatives in some cases).
Method signatures should be formated with a space after the scope (-/+ char) and a space between each method segment.
Variables have to be named as descriptively as possible and single letter names should be reserved to
The asterisk indicating pointers is sticker with the variable name, with a space before :
Property instances should be used instead of simple instances variables. Direct instance variables access may be reserved to initializer, dealloc and setter/getter methods.
Apple naming guidelines should be followed at all time.
When needed, comments have to be used to explain why a piece of code does something. Most of the comments could be avoided by great code formatting and variable/methods naming.
dealloc method should be placed at the top of the implementation, with
init just behind.
init methods should be formatted as follows :
instancetype is, here, prefered to
id, essentially because your compiler and IDE can check your code and autocomplete better.
NSDictionnary haves literal notations that has to be used when creating immutable instances of those objects.
Constants should be declared as static constantes instead of
#define can be used only as an explicit macro.
Use the macro
NS_ENUM()included with the SDK instead of
enum. It has stronger type checking and code completion.
Private properties should be declared in the implementation file using a class extension. Man should avoid named categories, unless when extending external classes.
Images should be named as a Camel Cased string in very descriptive way. It’s name must help preserve project organization and developers sanity. It is prefixed with the name of the class where it is used (wich has to be correctly named as well). For example :
Images can be grouped in folders when they are used for similar purposes.
Singleton objects should use a thread safe implementation for creating or getting their shared instances.
Each physical file should be kept in the project folder. Groups in Xcode may be reflected by folders in the file system. Source files should be grouped by types and modules for greater lisibility.
Github’s documentation is less complete than the NYTimes’ one. It is considered as a subclass of Apple’s official Coding Guidelines for Cocoa. It contains some interesting points of view.
Tabs may be used instead of spaces (configure your Xcode that way). You can use as many empty lines as you want to divide code into logical chunks.
Documentation and organization
Make use of
#pragma mark - to categorize methods into functional groupings and protocol implementations. A good practice could be to group methods that override methods from the same super class.
Github suggest that you should declare an ivar only if you need to change its type from its declared property. Actually, I didn’t know that it was possible, but it sounds nice. Prefer exposing an immutable type for a property, it’s a valid reason to declare an ivar for a property.
Don’t use a space between an object type and the protocol it conforms to. C functions should have no space before the opening parenthesis. It is suggested to name C functions just like Objective-C classes (with a capital letter at the beginning) but I don’t think it is a good practice.
Each long form ternary operator should be wrapped in parenthesis for readability. Il might be used only for assignments and arguments. The shirt form can avoid parenthesis.
Separate binary operands with a single space, but unary operands with none.
All the curvy braces should begin on the same line as their associated statement. They should end on a new line. Put a single space between the keyword and the parenthesis. No spaces between parenthesis and their content. (I particularly love this list !)
Error handling and exceptions
You should use exceptions only to preserve from programmer error, for example to force the override of a method (abstract).
NSError should be passed as reference in methods that need to indicate errors.
Google’s style guide is the most complete and accomplished proposal. It is based on Apple’s Cocoa Coding Guidelinesand Google’s Open Source C++ Style Guide. In this guide too, I picked some interesting things.
The maximum line length for Objective-C should be 100 colums. You may set Xcode to display a visual limit in text editor. *Please note that it is corresponding to the size of a text window with inspectors displayed on both side and the splitter view in the center. *
You should always keep your class simple. Don’t make it a “fourre-tout” by extending the class and it’s area. Methods that don’t need to be public may not. Better use private categories to prevent cluttering the public header.
Root headers should be imported before individual files. Also keep in mind to
#import Objective-C headers and
#include C headers.
When creating new temporary objects, use
autorelease on the same line as the declaration rather than a separate
release a few lines later in the same method.
dealloc methods should process instances in the same order as declared in the interface, for readability issues.