Skip to content

Style guide & coding conventions for Objective-C projects

Notifications You must be signed in to change notification settings

ribot/objective-c-style-guide

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 

Repository files navigation

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.

Whitespace

  • Spaces, not tabs.
  • Tab width of 4.
  • End files with a newline.
  • Make liberal use of vertical whitespace to divide code into logical chunks, but no more than one newline between each chunk.
  • Don’t leave trailing whitespace.
    • Not even leading indentation on blank lines.

Documentation and Organization

  • All public method declarations should be documented.
  • Comments should be Doxygen-style.
  • Document whether object parameters allow nil as a value.
  • Comments in code should be used to describe what a logical chunk does. Use your judgement and add comments where you think something needs explaining. In other words, do not explain what each line of code does, but give a high level description of what a logical chunk of code does if you think it is needed.
  • 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 {}

#pragma mark - Helpers

Declarations

  • Always declare memory-management semantics on every property.
  • Declare properties readonly if they are only set once in -init.
  • Don't use @synthesize unless the compiler requires it. Note that optional properties in protocols must be explicitly synthesized in order to exist.
  • Avoid weak properties whenever possible. A long-lived weak reference is usually a code smell that should be refactored out.
  • Instance variables should be prefixed with an underscore (just like when implicitly synthesized).
  • Constructors should generally return instancetype rather than id.
  • Don't put a space between an object type and the protocol it conforms to.
@property (nonatomic, strong) NSObject<Protocol> *object;

Expressions

  • 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. (Use @[thing] instead of [[NSArray alloc] initWith...).
  • Use [RBObject new] instead of [[RBObject alloc] init].
  • Comparisons should be explicit, including BOOLs.
if (boolean == YES) {
    // Do something
}

if (thing1 == thing2) {
    // Do something
}
  • Prefer positive comparisons to negative.
  • Long form ternary operators should only used for assignment and arguments.
Blah *a = (stuff == thing) ? foo : bar;
  • 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();
}

Control Structures

  • Always surround control structure bodies with curly braces.
  • Starting curly braces should begin on the same line as the control structure and closing braces should be on a new line.
  • else or else if control structures should be on the same line as the previous ending curly brace.
  • Put a single space after keywords and before their parentheses.
  • No spaces between parentheses and their contents.
  • Return and break early.
if (somethingIsBad == YES) {
    return;
}

if (something == nil) {
    // do stuff
} else {
    // do other stuff
}

Exceptions and Error Handling

  • Don't use exceptions for flow control.
  • Use exceptions only to indicate programmer error.

Blocks

  • 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.
void (^blockName1)() = ^{
    // do some things
};

id (^blockName2)(id) = ^id (id args) {
    // do some things
};

Literals

  • Avoid making numbers a specific type unless necessary (for example, prefer 5 to 5.0).
  • Dictionary literals should have no space between the key and the colon, and a single space between colon and value.
NSArray *theStuff = @[@"One", @"Two", @"Three"];

NSDictionary *keyedStuff = @{GHDidCreateStyleGuide: @YES, RBDidChangeCodeStyle: @YES};
  • Longer or more complex literals should be split over multiple lines:
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

  • 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. Some older projects use the Class+ForSubclassEyesOnly naming.

About

Style guide & coding conventions for Objective-C projects

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published