1、語言
應該使用US英語。
應該:
UIColor *baseColor = [UIColor whiteColor];
2、代碼組織
1、變量盡量以描述性的方式來命名。單個字符的變量命名應該盡量避免,除了在for()循環。
星號表示變量是指針。例如:
NSString *text
既不是 NSString* text
也不是 NSString * text,除了一些特殊情況下常量。
私有變量應該盡可能代替實例變量的使用。盡管使用實例變量是一種有效的方式,但更偏向于使用屬性來保持代碼一致性。
通過使用’back’屬性(_variable,變量名前面有下劃線)直接訪問實例變量應該盡量避免,除了在初始化方法(init, initWithCoder:, 等…),dealloc 方法和自定義的setters和getters。
2、所有屬性特性應該顯式地列出來,有助于新手閱讀代碼。屬性特性的順序應該是storage、atomicity,與在Interface Builder連接UI元素時自動生成代碼一致。
應該:
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) NSString *tutorialName;
3、在函數分組和protocol/delegate實現中使用#pragma mark -來分類方法。
4、每一行的最大長度,在Xcode > Preferences > Text Editing > Page guide at column中將最大行長設置為80,過長的一行代碼將會導致可讀性問題。
5、在方法簽名中,應該在方法類型(-/+ 符號)之后有一個空格。在方法各個段之間應該也有一個空格(符合Apple的風格)。在參數之前應該包含一個具有描述性的關鍵字來描述參數。
6、方法大括號和其他大括號(if/else/switch/while 等.)總是在同一行語句打開但在新行中關閉。
7、在方法之間應該有且只有一行,這樣有利于在視覺上更清晰和更易于組織。在方法內的空白應該分離功能,但通常都抽離出來成為一個新方法。
8、如果一個函數有特別多的參數或者名稱很長,應該分行,以冒號進行對齊。
9、在書寫協議的時候注意用<>括起來的協議和類型名之間是沒有空格的,比如DemoClass(),這個規則適用所有書寫協議的地方,包括函數聲明、類生命、實例變量等等。
10、應該使用可讀性更好的語法來構造NSArray、NSDictionary等數據結構,避免冗長的alloc、init方法。
如果構造代碼寫在一行,需要在括號兩端留一個空格,使得被構造的元素與構造語法區分開來:
NSArray array = @[ [foo description], [bar description] ];
NSDictionary dict = @{ NSForegroundColorAttributeName:[NSColor redColor] };
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;
11、點語法應該總是被用來訪問和修改屬性,因為它使代碼更加簡潔。[]符號更偏向于用在其他例子。
應該:
NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
不應該:
NSInteger arrayCount = self.array.count;
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
13、當需要注釋時,注釋應該用來解釋這段特殊代碼為什么要這樣做。任何被使用的注釋都必須保持最新或被刪除。
一般都避免使用塊注釋,因為代碼盡可能做到自解釋,只有當斷斷續續或幾行代碼時才需要注釋。
14、Apple命名規則盡可能堅持,特別是與這些相關的memory management rules (NARC)。
長的,描述性的方法和變量命名是好的。
應該:
UIButton *settingsButton;
常量應該使用駝峰式命名規則,所有的單詞首字母大寫和加上與類名有關的前綴。
static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
屬性也是使用駝峰式,但首單詞的首字母小寫。對屬性使用auto-synthesis,而不是手動編寫@synthesize語句,除非你有一個好的理由。
應該:
@property (strong, nonatomic) NSString *descriptiveVariableName;
15、當使用enum時,推薦使用新的固定基本類型規格,因為它有更強的類型檢查和代碼補全。現在SDK有一個宏NS_ENUM()來幫助和鼓勵你使用固定的基本類型。
例如:
typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {
RWTLeftMenuTopItemMain,
RWTLeftMenuTopItemShows,
RWTLeftMenuTopItemSchedule
};
你也可以顯式地賦值(展示舊的k-style常量定義):
typedef NS_ENUM(NSInteger, RWTGlobalConstants) {
RWTPinSizeMin = 1,
RWTPinSizeMax = 5,
RWTPinCountMin = 100,
RWTPinCountMax = 500,
};
當在switch使用枚舉類型時,’default’是不需要的
16、Objective-C使用YES和NO。因為true和false應該只在CoreFoundation,C或C++代碼使用。既然nil解析成NO,所以沒有必要在條件語句比較。不要拿某樣東西直接與YES比較,因為YES被定義為1和一個BOOL能被設置為8位。
這是為了在不同文件保持一致性和在視覺上更加簡潔而考慮。
應該:
if (someObject) {}
if (![anotherObject boolValue]) {}
不應該:
if (someObject == nil) {}
if ([anotherObject boolValue] == NO) {}
if (isAwesome == YES) {} // Never do this.
if (isAwesome == true) {} // Never do this.
如果BOOL屬性的名字是一個形容詞,屬性就能忽略”is”前綴,但要指定get訪問器的慣用名稱。例如:
@property (assign, getter=isEditable) BOOL editable;
17、條件語句主體為了防止出錯應該使用大括號包圍,即使條件語句主體能夠不用大括號編寫(如,只用一行代碼)。這些錯誤包括添加第二行代碼和期望它成為if語句;還有,even more dangerous defect可能發生在if語句里面一行代碼被注釋了,然后下一行代碼不知不覺地成為if語句的一部分。除此之外,這種風格與其他條件語句的風格保持一致,所以更加容易閱讀。
應該:
if ?(!error) ?{
return success;
}
18、當訪問CGRect里的x, y, width, 或 height時,應該使用CGGeometry函數而不是直接通過結構體來訪問。引用Apple的CGGeometry:
在這個參考文檔中所有的函數,接受CGRect結構體作為輸入,在計算它們結果時隱式地標準化這些rectangles。因此,你的應用程序應該避免直接訪問和修改保存在CGRect數據結構中的數據。相反,使用這些函數來操縱rectangles和獲取它們的特性。
應該:
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);
不應該:
CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };
19、單例對象應該使用線程安全模式來創建共享實例。
- (instancetype)sharedInstance {
? ?static id sharedInstance = nil;
? static dispatch_once_t onceToken;
? dispatch_once(&onceToken,{
? sharedInstance = [[self alloc] init];
? });
return sharedInstance;
}
20、換行符是一個很重要的主題,因為它的風格指南主要為了打印和網上的可讀性。
例如:
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
一行很長的代碼應該分成兩行代碼,下一行用兩個空格隔開。
21、項目盡量不要有硬編碼
22、類名以大寫字母開頭,應該包含一個名詞來表示它代表的對象類型,同時可以加上必要的前綴,比如NSString, NSDate, NSScanner, NSApplication等等。
23、一個委托方法的第一個參數是觸發它的對象,第一個關鍵詞是觸發對象的類名,除非委托方法只有一個名為sender的參數:
根據委托方法觸發的時機和目的,使用should,will,did等關鍵詞
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
24、重中之重:整個工程中風格要統一