These guidelines build on Apple's existing Coding Guidelines for Cocoa. Unless explicitly contradicted below, assume that all of Apple's guidelines apply as well.
- Tabs, not spaces.
- End files with a newline.
- Make liberal use of vertical whitespace to divide code into logical chunks.
- All method declarations should be documented.
- Comments should be hard-wrapped at 80 characters.
- Comments should be Tomdoc-style.
- Document whether object parameters allow
nilas a value. - Use
#pragma marks to categorize methods into functional groupings and protocol implementations, following this general structure:
#pragma mark Properties @dynamic someProperty; - (void)setCustomProperty:(id)value {} #pragma mark Lifecycle + (instancetype)objectWithThing:(id)thing {} - (instancetype)init {} #pragma mark Drawing - (void)drawRect:(CGRect) {} #pragma mark Another functional grouping #pragma mark GHSuperclass - (void)someOverriddenMethod {} #pragma mark NSCopying - (id)copyWithZone:(NSZone *)zone {} #pragma mark NSObject - (NSString *)description {}- Never declare an ivar unless you need to change its type from its declared property.
- Don’t use line breaks in method declarations.
- Prefer exposing an immutable type for a property if it being mutable is an implementation detail. This is a valid reason to declare an ivar for a property.
- Always declare memory-management semantics even on
readonlyproperties. - Declare properties
readonlyif they are only set once in-init. - Don't use
@synthesizeunless the compiler requires it. Note that optional properties in protocols must be explicitly synthesized in order to exist. - Declare properties
copyif they return immutable objects and aren't ever mutated in the implementation.strongshould only be used when exposing a mutable object, or an object that does not conform to<NSCopying>. - Instance variables should be prefixed with an underscore (just like when implicitly synthesized).
- Don't put a space between an object type and the protocol it conforms to.
@property (attributes) id<Protocol> object; @property (nonatomic, strong) NSObject<Protocol> *object;- C function declarations should have no space before the opening parenthesis, and should be namespaced just like a class.
void GHAwesomeFunction(BOOL hasSomeArgs);- Constructors should generally return
instancetyperather thanid. - Prefer C99 struct initialiser syntax to helper functions (such as
CGRectMake()).
CGRect rect = { .origin.x = 3.0, .origin.y = 12.0, .size.width = 15.0, .size.height = 80.0 };- Don't access an ivar unless you're in
-init,-deallocor a custom accessor. - Use dot-syntax when invoking idempotent methods, including setters and class methods (like
NSFileManager.defaultManager). - Use object literals, boxed expressions, and subscripting over the older, grosser alternatives.
- Comparisons should be explicit for everything except
BOOLs. - Prefer positive comparisons to negative.
- Long form ternary operators should be wrapped in parentheses and only used for assignment and arguments.
Blah *a = (stuff == thing ? foo : bar);- Short form,
nilcoalescing ternary operators should avoid parentheses.
Blah *b = thingThatCouldBeNil ?: defaultValue;- Separate binary operands with a single space, but unary operands and casts with none:
void *ptr = &value + 10 * 3; NewType a = (NewType)b; for (int i = 0; i < 10; i++) { doCoolThings(); }- Always surround
ifbodies with curly braces if there is anelse. Single-lineifbodies without anelseshould be on the same line as theif. - All curly braces should begin on the same line as their associated statement. They should end on a new line.
- Put a single space after keywords and before their parentheses.
- Return and break early.
- No spaces between parentheses and their contents.
if (somethingIsBad) return; if (something == nil) { // do stuff } else { // do other stuff }- Don't use exceptions for flow control.
- Use exceptions only to indicate programmer error.
- To indicate errors, use an
NSError **argument or send an error on a ReactiveCocoa signal.
- Blocks should have a space between their return type and name.
- Block definitions should omit their return type when possible.
- Block definitions should omit their arguments if they are
void. - Parameters in block types should be named unless the block is initialized immediately.
void (^blockName1)(void) = ^{ // do some things }; id (^blockName2)(id) = ^ id (id args) { // do some things };- Avoid making numbers a specific type unless necessary (for example, prefer
5to5.0, and5.3to5.3f). - The contents of array and dictionary literals should have a space on both sides.
- Dictionary literals should have no space between the key and the colon, and a single space between colon and value.
NSArray *theStuff = @[ @1, @2, @3 ]; NSDictionary *keyedStuff = @{ GHDidCreateStyleGuide: @YES };- Longer or more complex literals should be split over multiple lines (optionally with a terminating comma):
NSArray *theStuff = @[ @"Got some long string objects in here.", [AndSomeModelObjects too], @"Moar strings." ]; NSDictionary *keyedStuff = @{ @"this.key": @"corresponds to this value", @"otherKey": @"remoteData.payload", @"some": @"more", @"JSON": @"keys", @"and": @"stuff", };- Categories should be named for the sort of functionality they provide. Don't create umbrella categories.
- Category methods should always be prefixed.
- If you need to expose private methods for subclasses or unit testing, create a class extension named
Class+Private.