My Coding Style

My Coding Style

Published on: Jul 29, 2011

code coding style coding style Objective-C

My Code, My Rules.

This style guide is heavily influenced by the "Zarra Studios Coding Style Guide" [1], and whilst we agree on lots of things, there are major differences.

Spacing

  • Use only spaces, and indent 2 spaces at a time.
  • Keywords such as if, while, do, switch, etc. should not have a space after them.
  • One space should be used between - or + and the method return type.
  • Avoid wrapping lines - XCode does a good job at displaying long lines.
  • Wasted vertical space should be avoided. There should be only one empty line between methods.

Brackets

  • Method brackets should be on the following line and flush left (this might seem a waste of vertical space).
  • Code should be indented 2 spaces from the opening bracket.
  • Brackets in switches should be avoided but when needed they are to be left aligned with the case line and on their own line.
  • All other brackets should be inline.

Naming conventions and locations

  • Class names should follow the Pascal Case convention: should start as uppercase and use mixed case to delimit words.
  • File names should reflect the name of the class implementation that they contain - including case.
  • Variable and method names should follow the Camel Case convention: start as lowercase and then use mixed case. Each parameter should also follow this convention. Use descriptive names, the longer the better. Don't use single letter variables - the only exception is i used for incrementers.
  • For constant names use all caps with underscores between words.
  • Plural denotes a collection.
  • The pre-compiled header should always be named Prefix.pch and not Project_Prefix.pch or anything else. The only exception is when multiple targets are present and each target requires its own header- it should be named Prefix.pch
  • The info.plist should always be named Info.plist and not Project_Info.plist or anything else. The only exception is when multiple targets are present and the info.plist file should be named Target-Info.plist
  • The application delegate, if its a separate class, should be named AppDelegate and not Project_AppDelegate or anything else.
  • xib file names should end in view, menu or window and never in "controller".
  • Framework imports should be in the Prefix.pch and not in the individual class files.
  • String constants should be #define and stored in the Prefix.pch. The exception is a #define that is highly local to a specific class.
  • Protocol implementations should be separated out by #pragma marks.

 Memory Management

  • @property definitions should be used in place of iVars; direct iVar access should be avoided except during initialization of the variable and in the -viewDidUnload and -dealloc methods. The iVar should have the same name as the property with an underscore as prefix (this is against Apple's recommendation).
  • @synthesize and @dynamic are boiler-plate code that should be put at the top of the class just below the @implementation (each on a separate line).
  • When an object is released, the pointer should also be set to nil. These two calls should be on the same line:
    [object release], object = nil;
  • dealloc must be placed directly below the -init methods of any class or as the first methods if -initmethods are present.
  • Dot notation is to be used ONLY for properties i.e. to access the variables holding the state of the object.

 Method signatures

  • Method signatures should be left aligned. There should be a space after the scope (the plus or the minus sign). There should be a space between the method segments and between the class name and the star character in the parameter types.
    - (void)setExample:(NSString *)text;
  • Avoid writing long methods; the purpose of a method is to perform an operation. If this can be decomposed then extract reusable parts into their own methods.
  • Any method that is empty or just calls super should be removed from the source code as they are redundant.

 File locations

  • All class files should be stored in the Classes directory unless they belong to another subproject or library
  • Classes should be stored in subfolders based on their purpose or section of the app i.e. assign a folder to a group in XCode.
  • The only files that should be in the root of the project are: Prefix.pch, Info.plist, main.m, Default.png and icon.png (and their variants).

 Booleans

Boolean can only have 2 values: YES and NO. True and false are incorrect.

 Comments

There is no such thing as too many comments. Comments are desirable but not required as the code should be self-explanatory.

 Avoid casting

This generally indicates you are probably doing something wrong and trying to lie to the compiler. Use id as the last resort.

 Libraries / submodules

Each library should contain a main .f file, named LibraryName.h, that includes all relevant headers of the classes defined/extended. It should also contain any settings, default values, etc.

 Debugging

  • ZAssert should be used in place of NSAssert and should be used whenever a critical check is required.
  • DLog should be used in place of NSLog in all situations. NSLog should not be used directly in the code.
  • Whenever a situation occurs that "shouldn't" then an ALog should be used so that those situations can be captured via assertions or logs.

 Golden Path

When coding with conditionals, the left hand margin of the code should be the "golden" or "happy" path. We should never see:

- (void)someMethod
  {
    if ([someOther boolValue]) {
      //Do something important
    }
  }

That is difficult to read. Instead the code should fail early and fail often:

- (void)someMethod
  {
    if (![someOther boolValue]) return;
    //Do something important
  }

Likewise, a method should not be bisected with a conditional as follows:

- (void)someMethod
  {
    if ([someOther boolValue]) {
      //Do something important
    } else {
      //Do something else important
    }
  }

This is also hard to read and should be re-written as:

- (void)someMethod
  {
    if ([someOther boolValue]) {
      //Do something important
      return;
    }
    //Do something else important
  }

There is one situation where a bisection of the code is acceptable:

- (void)someMethod
  {
    if ([someOther boolValue]) {
      //Do something important
    } else {
      //Do something else important
    }
    //Do this no matter what
  }

The goal here is to make the code on the left margin to be the "expected" code execution path and the code that is indented to be the exception. Consistency in this area is important to code readability.

 No Exception ;)

Throwing exceptions should be avoided - these are to be used for truly exceptional scenarios and not for controlling logic flow.

 Boyscout

Whenever you are in a piece of code it should be left cleaner than when you found it if possible. If you find code that violates this guide, correct it. If the code is out dated then update it.

 Version control

  • Use version control!!!
  • git is the preferred choice.
  • don't commit code that generated warnings!!!
  • run all unit tests before committing. Make sure they all pass.

 Other things to consider

  • Keep the code simple.
  • Like all premature things, premature optimisation is bad.
  • Don't overdesign.
  • Don't underdesign.
  • Avoid bugs.
  • Be consistent.
  • Use common sense.

References:

This is a live document that is going to evolve over time. Feel free to get in touch with suggestions, etc. Thank you!