一.條件語(yǔ)句
1.條件語(yǔ)句體應(yīng)該總是被大括號(hào)包圍來(lái)避免錯(cuò)誤啊胶,即使可以不用茫打。
推薦:
if(!error){
return success;
}
不推薦:
if(!error)
return success;
不推薦:
if(!error) return success;
2.不要使用尤他表達(dá)式累贤。(尤他表達(dá)式是指拿一個(gè)常量去和變量比較而不是拿變量去和常量比較)
推薦:
if([myValue isEqual:@42]){
...
}
不推薦:
if([@42 isEqual:myValue]){
...
}
推薦:
if(someObject){...
if(![someObject boolValue]){...
if(!someObject){...
不推薦:
if(someObject == YES) { ... //Wrong
if(myRawValue == YES){... // Never do this
if([someObject boolValue] == NO) { ...
3.黃金大道:
“當(dāng)編寫(xiě)條件語(yǔ)句的時(shí)候狱杰,左邊的代碼間距應(yīng)該是一個(gè)“黃金”或者“快樂(lè)”的大道差凹。 這是說(shuō)期奔,不要嵌套if語(yǔ)句。多個(gè) return 語(yǔ)句是OK的危尿∧琶龋”
推薦:
-(void)someMethod {
if(![someOther boolValue]){
return;
}
// Do something import
}
不推薦:
-(void)someMethod {
if([someOther boolValue]) {
// Do something important
}
}
4.復(fù)雜表達(dá)式:當(dāng)有一個(gè)復(fù)雜的if子句的時(shí)候,應(yīng)該把它們提取出來(lái)賦給一個(gè)BOOL變量脚线,這樣可以讓邏輯更清楚搁胆,而且讓每個(gè)子句的意義體現(xiàn)出來(lái)。
BOOL nameContainsSwift = [sessionName containsString:@"swift"];
BOOL isCurrentYear = [sessionDateCompontents year] == 2014;
BOOL isSwiftSession = nameContainsSwift && isCurrentYear;
if(isSwiftSession) {
// Do something very cool
}
5.三元運(yùn)算符:應(yīng)該只用在它能讓代碼更加清楚的地方。一個(gè)條件語(yǔ)句的所有的變量應(yīng)該是已經(jīng)被求值的渠旁。計(jì)算多個(gè)條件子句通常會(huì)讓語(yǔ)句更加難以理解攀例。
推薦:
result = a > b ? x : y;
不推薦:
result = a > b ? x = c > d ? c : d : y;
二. case語(yǔ)句
1.除非編譯器強(qiáng)制要求,括號(hào)在case語(yǔ)句里是不必要的顾腊。但是當(dāng)一個(gè)case包含了多行語(yǔ)句的時(shí)候粤铭,需要加上括號(hào)。
2.當(dāng)在switch語(yǔ)句里面使用一個(gè)可枚舉變量的時(shí)候杂靶,default是不必要的梆惯。比如:
switch(menuType){
case ZOCEnumNone:
//...
break;
case ZOCEnumValue1:
//...
break;
case ZOCEnumValue2:
//...
break;
}
3.Enumarated Types 枚舉類(lèi)型
當(dāng)使用enum的時(shí)候,建議使用新的固定的基礎(chǔ)類(lèi)型定義吗垮,因?yàn)樗懈鼜?qiáng)大的類(lèi)型檢查和代碼補(bǔ)全垛吗。
typedef NS_ENUM(NSUInteger,ZOCMachineState){
ZOCMachineStateNone,
ZOCMachineStateIdle,
ZOCMachineStateRunning,
ZOCMachineStatePaused,
};
三.命名
1.通用的約定:推薦使用長(zhǎng)的,描述性的方法和變量名
推薦:
UIButton *settingsButton;
不推薦:
UIButton *setBut;
2.常量:
常量應(yīng)該使用駝峰命名法烁登,應(yīng)該用相關(guān)的類(lèi)名作為前綴怯屉。
//推薦:
static const NSTimeInterval ZOCSignInViewFadeOutAnimationDuration = 0.4;
//不推薦:
static const NSTimeInterval fadeOutTime = 0.4
常量應(yīng)該盡量使用in-line 的字符串字面值或者數(shù)字,這樣便于經(jīng)常用到的時(shí)候復(fù)用饵沧,并且可以快速修改而不用查找和替換锨络。常量應(yīng)該用static聲明,并且不要使用#define狼牺,除非它就是明確作為一個(gè)宏來(lái)用的羡儿。
//推薦
static NSString *const ZOCatchControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";
static const CGFloat ZOCImageThumbnailHeight = 50.0f;
//不推薦
#define CompanyName @"Apple Inc."
#define magicNumber 42
常量應(yīng)該在interface 文件中這樣被聲明:
extern NSString *const ZOCatchControllerDidClearCacheNotification;
并且應(yīng)該在實(shí)現(xiàn)文件中實(shí)現(xiàn)它的定義。
3.方法
對(duì)于方法簽名是钥,在方法類(lèi)型(-/+ 符號(hào))后應(yīng)該要有一個(gè)空格掠归。方法段之間也應(yīng)該有一個(gè)空格。在參數(shù)名稱(chēng)之前總是應(yīng)該有一個(gè)描述性的關(guān)鍵字咏瑟。
(“and”不應(yīng)該用作闡明有多個(gè)參數(shù))
//推薦:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
//不推薦:
- (void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height; // Never do this.
4.字面值
NSString, NSDictionary, NSArray 和 NSNumber 字面值應(yīng)該用在任何創(chuàng)建不可變的實(shí)例對(duì)象拂到。(nil不能放進(jìn)NSArray 和 NSDictionary里痪署,這會(huì)導(dǎo)致 Crash码泞。)
例子:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
對(duì)于那些可變的副本,推薦使用明確的如NSMutableArray, NSMutableString這些類(lèi)狼犯。
四.類(lèi)
1.類(lèi)名:類(lèi)名應(yīng)該加上三個(gè)大寫(xiě)字母作為前綴(減少objective-c沒(méi)有命名空間所帶來(lái)的問(wèn)題)余寥。建議在定義Core Data 對(duì)象時(shí)嚴(yán)格遵循這個(gè)約定,因?yàn)槟阕詈罂赡馨涯愕?Managed Object Model 和其他(第三方庫(kù)) 的Managed Object Model 合并悯森。
當(dāng)你創(chuàng)建一個(gè)子類(lèi)的時(shí)候宋舷,應(yīng)該把說(shuō)明性的部分放在前綴和父類(lèi)名的中間。如果你有一個(gè)ZOCNetworkClient類(lèi)瓢姻,子類(lèi)的名字會(huì)是ZOCTwitterNetworkClient祝蝠。
2.Initializer 和 dealloc 初始化
推薦的代碼組織方式:將 dealloc 方法放在實(shí)現(xiàn)文件的最前面(直接在@synthesize以及 @dynamic 之后),init 應(yīng)該放在 dealloc 之后。
init 方法結(jié)構(gòu):
-(instancetype)init
{
self = [super init];
if(self){
//Custom initialization
}
return self;
}
~alloc表示對(duì)象分配內(nèi)存绎狭,這個(gè)過(guò)程涉及分配足夠的可用內(nèi)存來(lái)保存對(duì)象细溅,寫(xiě)入 isa 指針,初始化 retain 的計(jì)數(shù)儡嘶,并且初始化所有的實(shí)例變量喇聊。
~init 是表示初始化對(duì)象,這意味著把對(duì)象放到了一個(gè)可用的狀態(tài)蹦狂。這通常是指把對(duì)象的實(shí)例變量賦給了可用的值誓篱。
- instancetype: 在 alloc 或者 init 中,強(qiáng)烈建議對(duì)所有返回類(lèi)的實(shí)例的類(lèi)方法和實(shí)例方法使用 instancetype 類(lèi)型凯楔。
4.如果可能窜骄,請(qǐng)盡量避免使用單例而是依賴(lài)注入。如果一定要使用摆屯,請(qǐng)使用一個(gè)線(xiàn)程安全的模式來(lái)創(chuàng)建共享的實(shí)例啊研。對(duì)于GCD,用dispatch_once()函數(shù)(把一些東西執(zhí)行一次)就可以鸥拧。
5.屬性應(yīng)該盡可能描述性地命名党远,避免縮寫(xiě),并且是小寫(xiě)字母開(kāi)頭的駝峰命名富弦。
應(yīng)該總是使用setter和getter方法訪問(wèn)屬性沟娱,除了init 和 dealloc方法。因?yàn)椋?br>
a. 使用setter會(huì)遵守定義的內(nèi)存管理語(yǔ)義(strong,weak,copy...)
b. KVO通知會(huì)被自動(dòng)執(zhí)行
c. 更容易debug
d. 允許在一個(gè)單獨(dú)的地方為設(shè)置值添加額外的邏輯
6.Init 和 Dealloc
永遠(yuǎn)不能在init(以及其他初始化函數(shù))里面用getter 和 setter 方法腕柜,而是直接訪問(wèn)實(shí)例變量济似。
使用setter getter 方法的時(shí)候盡量使用點(diǎn)語(yǔ)法。