└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # This repository is no longer active. 2 | 3 | ----- 4 | 5 | These guidelines build on Apple's existing [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html). 6 | Unless explicitly contradicted below, assume that all of Apple's guidelines apply as well. 7 | 8 | ## Whitespace 9 | 10 | * Tabs, not spaces. 11 | * End files with a newline. 12 | * Make liberal use of vertical whitespace to divide code into logical chunks. 13 | * Don’t leave trailing whitespace. 14 | * Not even leading indentation on blank lines. 15 | 16 | ## Documentation and Organization 17 | 18 | * All method declarations should be documented. 19 | * Comments should be hard-wrapped at 80 characters. 20 | * Comments should be [Tomdoc](http://tomdoc.org/)-style. 21 | * Document whether object parameters allow `nil` as a value. 22 | * Use `#pragma mark`s to categorize methods into functional groupings and protocol implementations, following this general structure: 23 | 24 | ```objc 25 | #pragma mark Properties 26 | 27 | @dynamic someProperty; 28 | 29 | - (void)setCustomProperty:(id)value {} 30 | 31 | #pragma mark Lifecycle 32 | 33 | + (instancetype)objectWithThing:(id)thing {} 34 | - (instancetype)init {} 35 | 36 | #pragma mark Drawing 37 | 38 | - (void)drawRect:(CGRect) {} 39 | 40 | #pragma mark Another functional grouping 41 | 42 | #pragma mark GHSuperclass 43 | 44 | - (void)someOverriddenMethod {} 45 | 46 | #pragma mark NSCopying 47 | 48 | - (id)copyWithZone:(NSZone *)zone {} 49 | 50 | #pragma mark NSObject 51 | 52 | - (NSString *)description {} 53 | ``` 54 | 55 | ## Declarations 56 | 57 | * Never declare an ivar unless you need to change its type from its declared property. 58 | * Don’t use line breaks in method declarations. 59 | * 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. 60 | * Always declare memory-management semantics even on `readonly` properties. 61 | * Declare properties `readonly` if they are only set once in `-init`. 62 | * Don't use `@synthesize` unless the compiler requires it. Note that optional properties in protocols must be explicitly synthesized in order to exist. 63 | * Declare properties `copy` if they return immutable objects and aren't ever mutated in the implementation. `strong` should only be used when exposing a mutable object, or an object that does not conform to ``. 64 | * Avoid `weak` properties whenever possible. A long-lived weak reference is usually a code smell that should be refactored out. 65 | * Instance variables should be prefixed with an underscore (just like when implicitly synthesized). 66 | * Don't put a space between an object type and the protocol it conforms to. 67 | 68 | ```objc 69 | @property (attributes) id object; 70 | @property (nonatomic, strong) NSObject *object; 71 | ``` 72 | 73 | * C function declarations should have no space before the opening parenthesis, and should be namespaced just like a class. 74 | 75 | ```objc 76 | void GHAwesomeFunction(BOOL hasSomeArgs); 77 | ``` 78 | 79 | * Constructors should generally return [`instancetype`](http://clang.llvm.org/docs/LanguageExtensions.html#related-result-types) rather than `id`. 80 | * Prefer helper functions (such as `CGRectMake()`) to C99 struct initialiser syntax. 81 | 82 | ```objc 83 | CGRect rect = CGRectMake(3.0, 12.0, 15.0, 80.0); 84 | ``` 85 | 86 | ## Expressions 87 | 88 | * Don't access an ivar unless you're in `-init`, `-dealloc` or a custom accessor. 89 | * Use dot-syntax when invoking idempotent methods, including setters and class methods (like `NSFileManager.defaultManager`). 90 | * Use object literals, boxed expressions, and subscripting over the older, grosser alternatives. 91 | * Comparisons should be explicit for everything except `BOOL`s. 92 | * Prefer positive comparisons to negative. 93 | * Long form ternary operators should be wrapped in parentheses and only used for assignment and arguments. 94 | 95 | ```objc 96 | Blah *a = (stuff == thing ? foo : bar); 97 | ``` 98 | 99 | * Short form, `nil` coalescing ternary operators should avoid parentheses. 100 | 101 | ```objc 102 | Blah *b = thingThatCouldBeNil ?: defaultValue; 103 | ``` 104 | 105 | * Separate binary operands with a single space, but unary operands and casts with none: 106 | 107 | ```c 108 | void *ptr = &value + 10 * 3; 109 | NewType a = (NewType)b; 110 | 111 | for (int i = 0; i < 10; i++) { 112 | doCoolThings(); 113 | } 114 | ``` 115 | 116 | ## Control Structures 117 | 118 | * Always surround `if` bodies with curly braces if there is an `else`. Single-line `if` bodies without an `else` should be on the same line as the `if`. 119 | * All curly braces should begin on the same line as their associated statement. They should end on a new line. 120 | * Put a single space after keywords and before their parentheses. 121 | * Return and break early. 122 | * No spaces between parentheses and their contents. 123 | 124 | ```objc 125 | if (somethingIsBad) return; 126 | 127 | if (something == nil) { 128 | // do stuff 129 | } else { 130 | // do other stuff 131 | } 132 | ``` 133 | 134 | ## Exceptions and Error Handling 135 | 136 | * Don't use exceptions for flow control. 137 | * Use exceptions only to indicate programmer error. 138 | * To indicate errors, use an `NSError **` argument or send an error on a [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa) signal. 139 | 140 | ## Blocks 141 | 142 | * Blocks should have a space between their return type and name. 143 | * Block definitions should omit their return type when possible. 144 | * Block definitions should omit their arguments if they are `void`. 145 | * Parameters in block types should be named unless the block is initialized immediately. 146 | 147 | ```objc 148 | void (^blockName1)(void) = ^{ 149 | // do some things 150 | }; 151 | 152 | id (^blockName2)(id) = ^ id (id args) { 153 | // do some things 154 | }; 155 | ``` 156 | 157 | ## Literals 158 | 159 | * Avoid making numbers a specific type unless necessary (for example, prefer `5` to `5.0`, and `5.3` to `5.3f`). 160 | * The contents of array and dictionary literals should have a space on both sides. 161 | * Dictionary literals should have no space between the key and the colon, and a single space between colon and value. 162 | 163 | ``` objc 164 | NSArray *theStuff = @[ @1, @2, @3 ]; 165 | 166 | NSDictionary *keyedStuff = @{ GHDidCreateStyleGuide: @YES }; 167 | ``` 168 | 169 | * Longer or more complex literals should be split over multiple lines (optionally with a terminating comma): 170 | 171 | ``` objc 172 | NSArray *theStuff = @[ 173 | @"Got some long string objects in here.", 174 | [AndSomeModelObjects too], 175 | @"Moar strings." 176 | ]; 177 | 178 | NSDictionary *keyedStuff = @{ 179 | @"this.key": @"corresponds to this value", 180 | @"otherKey": @"remoteData.payload", 181 | @"some": @"more", 182 | @"JSON": @"keys", 183 | @"and": @"stuff", 184 | }; 185 | ``` 186 | 187 | ## Categories 188 | 189 | * Categories should be named for the sort of functionality they provide. Don't create umbrella categories. 190 | * Category methods should always be prefixed. 191 | * If you need to expose private methods for subclasses or unit testing, create a class extension named `Class+Private`. 192 | --------------------------------------------------------------------------------