#Objective-C Style Guide
##Comments
###General Info
Block comments /**/
should be avoided in favor of //
(though they are not banned).
Inside comments, references to variables, classes and protocols should be surrounded by |.
// This class is responsible for keeping up to date a list of |Item| objects.
Every file should start with a comment referencing filename, project name, author, creation date and copyright info. This template should be used :
//
// ${filename}
// $(projectname}
//
// Created by ${author} on ${date}.
// Copyright ${year} ${company}. All rights reserved.
//
All classes / protocol / method declaration should be preceded by a comment defining what this class / protocol / method does. Method comment should explicit if the method is thread safe or not.
// This method is responsible for updating a list of |Item| objects over the network.
// It downloads, and keeps track of them. It is not thread safe.
In addition, every public method (accessible outside the scope of the object) should describe precisely its expected argument, return value, any side effect, and assumptions it has.
// This delegate method is called when the download is finished
// |someData| is the data downloaded
// |anURL| is a recall of the |NSURL| that was used to download data.
// if something went wrong, |someData| will be nil
- (void)data:(NSData*)someData forURL:(NSURL*)anURL;
Instance variables should be documented inline. The comment should mention if the link is weak / strong or if its data is copied.
NSURL *URL_; // this URL is used to download the file
id<FileDownloadOperationDelegate> delegate_; // (weak) delegate
NSString *header_; // (copy) this header is added at the begining of the file
Naming rules should follow Apple naming rules for the most parts.
All acronyms should use all caps. ex URL RSS HTTP
instead of Url Rss Http
.
Here is a quick summary :
Filenames should be the same as the class name, using the same case.
-
Objective-C files should end with
.h
for headers and.m
for implementation files.For example,
RSSReader
should be declared and implemented inRSSReader.h
andRSSReader.m
. -
Objective-C++ files should end with
.h
for headers and.mm
for implementation files -
C Files should be named
.h
for header files and.c
for implementation files -
C++ Files should be named
.h
for header files and.cc
for implementation files
Class names should start with an uppercase and each word should start with an uppercase letter. Class names should not contain underscores.
Category names should be prefixed with 2 or 3 letters identifying the project. This is because Objective-C only has one namespace, and we should prevent name collision.
If we want to create a category for parsing for NSString
in project ABC, the category name should be NSString (ABCParsing)
and should be contained in NSString+ABCParsing.h
and NSString+ABCParsing.m
Method names should start with lower case and then use mixed case. Every subsequent parameter should start with a lower case. Ideally method names should start with a name, and sound like a sentence.
Parameter names should be explicit and mention a simplified version of the type. For obvious parameters, the should start with a
or an
and follow with a simplified version of the type.
// Prefered version
- (NSData*)getDataUsingURL:(NSURL*)sourceURL;
// Also possible
- (NSData*)getDataUsingURL:(NSURL*)anURL;
// Forbidden
- (NSData*)GetDataUsingURL:(NSURL*)anURL;
- (NSData*)getDataUsingURL:(NSURL*)foo;
- (NSData*)get_Data_Using_URL:(NSURL*)anURL;
- (NSData*)getDataUsingURL:(NSURL*)u;
Variable names should be explicit and descriptive, within reason. Xcode makes autocompletion easy, so we should not worry about using short name. Readability is key.
Again, obvious variables should start with a
or an
and follow with a simplified version of the type.
Collection variable names should be plural.
// Valid variable names
int numErrors;
NSURL *anURL;
NSMutableArray *items;
// Invalid
int w;
NSURL *myURL;
NSMutableArray *item;
Instance Variables should follow the same rules as local variables, except they should not start with a
or an
.
They should end with an underscore i.e. Account *mainAccount_;
. The reason behind this is that a common bug in Objective-C is the use of variable = ...
when the programmer really meant self.variable = ...
(which is equivalent to [self setVariable:...];
). Using this underscore forces the programer to think when he accesses the variable instead of using the property methods.
Constant names (#defines, enums, constant variables, etc...) should start with a lower k
and use mixed case to delimit words, i.e. kInvalidHandle
,kStatusCodeOK
.
For the purpose of encapsulation, member variables should be @private
.
When declaring a property, try to be as restrictive as possible concerning its usage. Most properties can be readonly, yet people declare them as @property (nonatomic, retain)
Clearly identify your designated initializer. It is absolutely important that only one init method of the child class calls super
init method. All other init method of the child class should call this designated initializer.
In order to prevent cluttering your header files, keep your private methods in your implementation (.m
) file using an anonymous category.
Exemple :
// ABC.h
@interface ABC : NSObject {
// some instance variables...
}
- (void)publicMethod;
@end
// ABC.m
#import "ABC.h"
@interface ABC ()
- (void)privateMethod;
@end
@implementation ABC
- (void)publicMethod{
//...
}
- (void)privateMethod{
//...
}
@end
On mobile devices, memory is a precious resource. autorelease
should be used only when necessary.
Prefer using [[... alloc] init
over convenience methods that return an autoreleased object, and release
your object as soon as you don't need it anymore.
You should use only spaces, not tabs. Indent with 2 spaces.
It easy quite easy to setup Xcode to do this : go to Xcode > Preferences > Text Editing > Indentation
.
- Set
Prefer indent using
toSpaces
- Set
Tab width
to2
- Set
indent width
to2
Braces should be put on the same line as the construct it refers to.
// valid
if (statusCode == kStatusCodeOK){
// ...
}
// invalid
if (statusCode == kStatusCodeOK)
{
// ...
}
Ideally try to write line of codes that are no longer than 80chars. This may sound archaic due to bigger screen size these days, but many programmers like to have two files side by side when coding.
You can make this rule easier to follow by going to Xcode > Preferences > Text Editing > Show Page Guide
There should be one space between -
or +
and the return type and no spacing in the parameter list, except between parameters.
// Valid
- (void)doSomethingWithFirst:(NSString *)firstString andSecond:(NSString *)secondString;
// Invalid
- (void) doSomethingWithFirst:(NSString *)firstString andSecond:(NSString *)secondString;
- (void)doSomethingWithFirst: (NSString *)firstString andSecond: (NSString *)secondString;
- (void)doSomethingWithFirst:(NSString *) firstString andSecond:(NSString *) secondString;
The spacing between the type and pointer star in (NSString *)
is optional but recommended.
It is also recommended to add a space between the method name and the opening brace.
- (void)doSomethingWithFirst:(NSString *)firstString andSecond:(NSString *)secondString {
// ...
}
#### Multi parameters
if the function is too long to fit on one line, then it should use one line per parameter, with colon aligned.
```objectivec
// Valid
- (void)doSomethingWithFirst:(NSString *)firstString
second:(NSString *)secondString
third:(NSString *)thirdString
andFourth:(NSString *)fourthString
// Invalid
- (void)doSomethingWithFirst:(NSString *)firstString
second:(NSString *)secondString third:(NSString *)thirdString
andFourth:(NSString *)fourthString
If the first keyword is shorter than the other ones, then align subsequent parameters using 2 spaces
- (void)act:(NSAction *)anAction
withLongKeyword:(NSString *)secondString
anOtherLongKeyWord:(NSString *)thirdString;
@private
,@public
,@property
and @synthesize
should always start on the first column.
@interface ItemManager : NSObject<FileDownloadOperationDelegate> {
@private
NSArray *items_;
FileDownloadOperation *fileOp;
}
Preprocessor conditions should use the same rule too.
- (void)start{
if ([self isCancelled])
{
#IFDEF DEBUG
NSLog(@"Debug");
#ENDIF
// ...
}
return
}
There should be no space between the type identifier and the name of the protocol encased in angle brackets.
@interface MyProtocoledClass : NSObject<FooProtocolDelegate> {
@private
id<BarProtocolDelegate> delegate_;
}