-
Notifications
You must be signed in to change notification settings - Fork 103
Objective C Style Guide
Joel Fischer edited this page Mar 25, 2015
·
8 revisions
These guidelines build on the Apple Coding Guidelines for Cocoa.
Partially based on the Github, New York Times, and Dropbox style guides.
- Spaces not tabs
- End files with a newline
- Use whitespace to divide code into chunks
- No trailing whitespace on lines
- Block comments should only exist for generated documentation. Inline comments should be used to explain why a particular piece of code exists, not what it does, which ought to be obvious if well written.
-
#pragma mark
methods into logical clusters. Use#pragma mark -
for major functionality groups,#pragma mark
for minor functionality groups.
- Label
TODO
andFIXME
comments with a name and date, follow the formatting shown below. - All
FIXME
comments must be fixed or deleted before a release.
// TODO: (Joel F.)[2015-03-22] Make sure we do the thing!
- Start with local imports (.m files import their own header first), then import global headers after.
- Import alphabetically.
- Use
strong
properties only if exposing a mutable object, or one that does not conform to<NSCopying>
. Prefercopy
in other instances. - Properties should be declared
nonatomic
by default unless there is a very good reason to useatomic
, which will be rare.
- If a property is mutable as an implementation detail, and does not need to be exposed as mutable, expose an immutable type for that property instead, and declare the ivar as mutable.
- Except for the above rule, always create properties instead of iVars. Private properties should be generated in an interface extension.
- iVars should be prefixed with an underscore, like implicitly synthesized ones.
- Access properties by iVar only if in
-init
,-dealloc
, or a custom accessor.
- Always initialize local variables, they will not be automatically initialized to
nil
or0
.
- If a private method can be a class method instead of an instance method, it should be a class method.
- Private methods should be prefixed with the project prefix
sdl
.
+ (void)sdl_privateClassMethod {}
- Protected methods should be declared in a class extension that subclasses implement and other classes do not.
- Prefer constants to inline string literals and numbers to more easily change them if necessary. Constants should be declared as
static
constants that are exported if public, and not#define
.
- Access properties and structs by dot-syntax, everything else (including idempotent methods) via bracket syntax.
- Binary operands should be separated with a space, unary and casts with no space.
for (int i = 0; i < 10; i++) {}
void *thing = &thing;
SuperThing newThing = (SuperThing)subThing;
-
NSString
,NSDictionary
,NSArray
, andNSNumber
literals should be used whenever possible. When turning a non-NSNumber number variable into an NSNumber, box the number with@()
.
NSString *string = @"string";
NSArray *array = @[ @1, @2, @3 ];
NSDictionary *dict = @{ @"key": value };
NSNumber *number = @42;
- Complex dictionary and array literals should be split across multiple lines.
NSDictionary *complexDict = @{
@"key1": value1,
@"key2": value2,
@"key3": value3
};
- To declare enumerations, use
NS_ENUM
. To declare options (bitmasks) useNS_OPTIONS
.
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
- For case blocks that are one line, you may omit braces. This will usually only happen if
break
is the only statement. - For case blocks that contain more than one line, wrap the lines in braces.
- When falling through a case statement, explicitly mark it with the comment
//fallthrough
- If possible,
default
should be an assertion.
switch(someEnum) {
case someEnumValue: {
// Do many things
} break;
case someEnumValue2: // Fallthrough
case someEnumValue3: {
// Do a few more things
} break;
default: NSAssert("Unknown enum value %@", @(someEnum));
}
- Conditionals should always contain braces.
- Comparisons should always be explicit except for
BOOL
values.BOOL
values are actually asigned char
, and explicit comparisons can lead to incorrect results in certain cases, such as setting aBOOL
to the result of an array's length. - Ternary operators should only be used when they improve clarity in assignments and arguments. They should be wrapped in parenthesis.
- Coalescing ternary operators should not use parenthesis.
if (someObject != nil) {
// Do the thing
} else if (someBool) {
// Do the other thing
} else {
// Do the last thing
}
NSString *someString = (isTrue ? @"YES" : @"NO");
NSString *someOtherString = optionalValue ?: defaultValue;
- Never use exceptions for flow control, only for programmer error.
- Use NSError to indicate all other fault types. To indicate that a method may error, receive an
NSError **
parameter. - Make sure to test for nullability on the error argument before setting it.
Copyright 2021 SmartDeviceLink Consortium