iOS代碼規(guī)范(翻譯自官方文檔)

點(diǎn)擊查看簡書原文

一. 格式化代碼

1. 指針“*”號的位置

? 如:NSString *varName; 

2. 空格 VS tabs

? 只允許使用空格,將編輯器設(shè)置為1個(gè)TAB = 2個(gè)字符縮進(jìn)

3. 每行的長度

? 每行最多不得超過100個(gè)字符
? 以15寸Macbook Pro的大小,每行100個(gè)字符時(shí)能最大化地同時(shí)容下編輯器和iPhone模擬器
? Google的80字符的標(biāo)準(zhǔn)有點(diǎn)少瘫想,這導(dǎo)致過于頻繁的換行(Objectve-C的代碼一般都很長)
? 通過 “Xcode => Preferences => TextEditing => 勾選Show Page Guide / 輸入
100 => OK” 來設(shè)置提醒

4. 方法的聲明和定義

? 在 - OR + 和返回值之間留1個(gè)空格丛晌,方法名和第一個(gè)參數(shù)間不留空格堵第。如:

- (void)doSomethingWithString:(NSString *)theString { 
... 
} 
//當(dāng)參數(shù)過長時(shí),每個(gè)參數(shù)占用一行沫屡,以冒號對齊拌牲。如: 
- (void)doSomethingWith:(GTMFoo *)theFoo 
rect:(NSRect)theRect 
interval:(float)theInterval { 
... 
} 

? 如果方法名比參數(shù)名短俱饿,每個(gè)參數(shù)占用一行,至少縮進(jìn)4個(gè)字符们拙,且為垂直對齊(而非使用冒號
對齊)稍途。如:

- (void)short:(GTMFoo *)theFoo 
longKeyword:(NSRect)theRect 
evenLongerKeyword:(float)theInterval { 
... 
} 

5. 方法的調(diào)用

? 調(diào)用方法沿用聲明方法的習(xí)慣阁吝。例外:如果給定源文件已經(jīng)遵從某種習(xí)慣砚婆,繼續(xù)遵從那種習(xí)慣。
? 所有參數(shù)應(yīng)在同一行中突勇,或者每個(gè)參數(shù)占用一行且使用冒號對齊装盯。如:

[myObject doFooWith:arg1 name:arg2 error:arg3]; 
或 
[myObject doFooWith:arg1 
name:arg2 
error:arg3]; 

? 和方法的聲明一樣,如果無法使用冒號對齊時(shí)甲馋,每個(gè)參數(shù)一行埂奈、縮進(jìn)4個(gè)字符、垂直對其(而非
使用冒號對齊)定躏。如:

[myObj short:arg1 
longKeyword:arg2 
evenLongerKeyword:arg3]; 

6. @public 和 @private

? @public 和 @private使用單獨(dú)一行账磺,且縮進(jìn)1個(gè)字符

7. Protocals

? 類型標(biāo)示符芹敌、代理名稱、尖括號間不留空格垮抗。
? 該規(guī)則同樣適用于:類聲明氏捞、實(shí)例變量和方法聲明。如:

@interface MyProtocoledClass : NSObject<NSWindowDelegate> { 
@private 
id<MyFancyDelegate> _delegate; 
} 

- (void)setDelegate:(id<MyFancyDelegate>)aDelegate; 

@end 

? 如果類聲明中包含多個(gè)protocal冒版,每個(gè)protocal占用一行液茎,縮進(jìn)2個(gè)字符。如:

@interface CustomViewController : ViewController< 
AbcDelegate, 
DefDelegate 
> { 
... 
} 

二. 命名

1. 類名

? 類名(及其category nameprotocol name)的首字母大寫辞嗡,寫使用首字母大寫的形式

2. 分割單詞

? 在面向特定應(yīng)用的代碼中捆等,類名應(yīng)盡量避免使用前綴,每個(gè)類都使用相同的前綴影響可讀性续室。
? 在面向多應(yīng)用的代碼中栋烤,推薦使用前綴。如:GTMSendMessage

3. 方法名

? 方法名的首字母小寫挺狰,且使用首字母大寫的形式分割單詞班缎。方法的參數(shù)使用相同的規(guī)則。
? 方法名+參數(shù)應(yīng)盡量讀起來像一句話(如:)她渴。在這里查看蘋果對方法命名的規(guī)范达址。
? getter的方法名和變量名應(yīng)相同。不允許使用“get”前綴趁耗。如:

- (id) getDelegate; // 禁止 
- (id)delegate; // 對頭 

? 本規(guī)則僅針對Objective-C代碼沉唠,C++代碼使用C++的習(xí)慣

4. 變量名

? 變量名應(yīng)使用容易意會(huì)的應(yīng)用全稱,且首字母小寫苛败,且使用首字母大寫的形式分割單詞
? 成員變量使用“”作為前綴(如:“NSString *_varName;”满葛。雖然這與蘋果的標(biāo)準(zhǔn)相沖突,但基于以下原因罢屈,仍使用“”作為前綴嘀韧。 )
? 使用“_”作為前綴,更容易在有代碼自動(dòng)補(bǔ)全功能的IDE中區(qū)分“屬性
(self.userInfo)”和“成員變量(_userInfo)”
? 常量(#define, enums, const等)使用小寫“k”作為前綴缠捌,首字母大寫來分割單詞锄贷。如:

kInvalidHandle

三. Cocoa 和 Objective-C特有的規(guī)則

1. 成員變量使用 @private。如:

@interface MyClass : NSObject { 
@private 
id _myInstanceVariable; 
} 
// public accessors, setter takes ownership 
- (id)myInstanceVariable; 
- (void)setMyInstanceVariable:(id)theVar; 
@end 

2. 初始化

? 在初始化方法中曼月,不要將變量初始化為“0”或“nil”谊却,那是多余的
? 內(nèi)存中所有的新創(chuàng)建的對象(isa除外)都是0,所以不需要重復(fù)初始化為“0”或“nil”

3. 避免顯式的調(diào)用 +new 方法

? 禁止直接調(diào)用 NSObject 的類方法 +new哑芹,也不要在子類中重載它炎辨。使用alloc和init方法

4. 保持公共API的簡潔性

5. #import VS #include

? 使用 #import 引入Ojbective-COjbective-C++頭文件,使用 #include 引入CC++
文件

6. import 根框架(root frameworks)聪姿,而非各單個(gè)文件

? 雖然有時(shí)我們僅需要框架(如Cocoa 或 Foundation)的某幾個(gè)頭文件碴萧,但引入根文件,編譯器會(huì)運(yùn)行的更快乙嘀。因?yàn)楦蚣埽?code>root frameworks)一般會(huì)預(yù)編譯,所以加載會(huì)更快破喻。再次強(qiáng)
調(diào):使用 #import 而非 #include 來引入Objective-C框架乒躺。如:

#import <Foundation/NSArray.h> // 禁止 
#import <Foundation/NSString.h> 
... 
#import <Foundation/Foundation.h> // 對頭

7. 創(chuàng)建對象時(shí)盡量使用autorelease

? 創(chuàng)建臨時(shí)對象時(shí),盡量同時(shí)在同一行中 autorelease 掉低缩,而非使用單獨(dú)的 release 語句
? 雖然這樣會(huì)稍微有點(diǎn)慢嘉冒,但這樣可以阻止因?yàn)樘崆?return 或其他意外情況導(dǎo)致的內(nèi)存泄露。
通盤來看這是值得的咆繁。如:

// 避免這樣使用(除非有性能的考慮) 
MyController* controller = [[MyController alloc] init]; 
// ... 這里的代碼可能會(huì)提前return ... 
[controller release]; 
// 這樣更好 
MyController* controller = [[[MyController alloc] init] autorelease]; 

8. 先autorelease讳推,再retain

? 在為對象賦值時(shí),遵從“先autorelease玩般,再retain
? 在將一個(gè)新創(chuàng)建的對象賦給變量時(shí)银觅,要先將舊對象release掉,否則會(huì)內(nèi)存泄露坏为。市面上有很多方法來handle這種情況究驴,這里選擇“先autorelease,再retain”的方法匀伏,這種方法不易引入error洒忧。注意:在循環(huán)中這種方法會(huì)“填滿”autorelease pool,稍稍影響效率够颠,但是
Google和我( :P )認(rèn)為這個(gè)代價(jià)是可以接受的熙侍。如:

- (void)setFoo:(GMFoo *)aFoo { 
  [foo_ autorelease]; // 如果foo_和aFoo是同一個(gè)對象(foo_ == aFoo),dealloc不會(huì)被調(diào)用 
  foo_ = [aFoo retain]; 
} 

9. dealloc的順序要與變量聲明的順序相同

? 這有利于review代碼
? 如果dealloc中調(diào)用其他方法來release變量,將被release的變量以注釋的形式標(biāo)注清楚

10. NSString的屬性的setter使用“copy

? 禁止使用retain履磨,以防止意外的修改了NSString變量的值蛉抓。如:

- (void)setFoo:(NSString *)aFoo { 
  [foo_ autorelease]; 
  foo_ = [aFoo copy]; 
} 

@property (nonatomic, copy) NSString *aString; 

11. 避免拋出異常(Throwing Exceptions

12. 對 nil 的檢查

? 僅在有業(yè)務(wù)邏輯需求時(shí)檢查 nil,而非為了防止崩潰
? 向 nil 發(fā)送消息不會(huì)導(dǎo)致系統(tǒng)崩潰剃诅,Objective-C運(yùn)行時(shí)負(fù)責(zé)處理巷送。

13. BOOL 陷阱

? 將int值轉(zhuǎn)換為BOOL時(shí)應(yīng)特別小心。避免直接和YES比較
? Objective-C中矛辕,BOOL被定義為unsigned char笑跛,這意味著除了YES (1)NO (0)外它還可以是其他值。禁止將int直接轉(zhuǎn)換(cast or convert)為BOOL如筛。
? 常見的錯(cuò)誤包括:將數(shù)組的大小堡牡、指針值或位運(yùn)算符的結(jié)果轉(zhuǎn)換(cast or convert)BOOL抒抬,因?yàn)樵?code>BOOL值的結(jié)果取決于整型值的最后一位
? 將整型值轉(zhuǎn)換為BOOL的方法:使用三元運(yùn)算符返回YES / NO杨刨,或使用位運(yùn)算符(&&, ||, !)
? BOOL_Boolbool之間的轉(zhuǎn)換是安全的擦剑,但是BOOLBoolean間的轉(zhuǎn)換不是安全的妖胀,所以將Boolean看成整型值芥颈。
? 在 Objective-C 中,只允許使用BOOL
? 如:

// 禁止 
- (BOOL)isBold { 
  return [self fontTraits] & NSFontBoldTrait; 
} 
- (BOOL)isValid { 
  return [self stringValue]; 
} 
// 對頭 
- (BOOL)isBold { 
  return ([self fontTraits] & NSFontBoldTrait) ? YES : NO; 
} 
- (BOOL)isValid { 
  return [self stringValue] != nil; 
} 
- (BOOL)isEnabled { 
  return [self isValid] && [self isBold]; 
} 

? 禁止直接將BOOLYES/NO比較赚抡,如:

// 禁止 
BOOL great = [foo isGreat]; 
if (great == YES) 
... 
// 對頭 
BOOL great = [foo isGreat]; 
if (great) 
... 

14. 屬性

? 命名:與去掉“_”前綴的成員變量相同爬坑,使用@synthesize將二者聯(lián)系起來。如:

// abcd.h 
@interface MyClass : NSObject { 
@private 
NSString *_name; 
} 
@property (copy, nonatomic) NSString *name; 
@end 
// abcd.m 
@implementation MyClass 
@synthesize name = _name; 
@end 

? 位置:屬性的聲明緊隨成員變量塊之后涂臣,中間空一行盾计,無縮進(jìn)。如上例所示
? 嚴(yán)把權(quán)限:對不需要外部修改的屬性使用readonly
? NSString使用copy而非retain
? CFType使用@dynamic, 禁止使用@synthesize
? 除非必須赁遗,使用nonatomic
? Cocoa Pattern

15. Delegate Pattern(委托)

? delegate對象使用assign署辉,禁止使用retain。因?yàn)?code>retain會(huì)導(dǎo)致循環(huán)索引導(dǎo)致內(nèi)存泄露,并且此類型的內(nèi)存泄露無法被Instrument發(fā)現(xiàn)岩四,極難調(diào)試 .
? 成員變量命名為_delegate哭尝,屬性名為delegate

16. Model/View/Controller

? ModelView分離
? Controller獨(dú)立于ViewController
? 不要在與view相關(guān)的類中添加過多的業(yè)務(wù)邏輯代碼,這讓代碼的可重用性很差
? Controller負(fù)責(zé)業(yè)務(wù)邏輯代碼剖煌,且Controller的代碼與view盡量無關(guān)
? 使用 @protocal 定義回調(diào)APIs材鹦,如果并非所有方法都是必須的,使用@optional標(biāo)示

四. 其他

1.init方法和dealloc方法是是最常用的方法耕姊,所以將他們放在類實(shí)現(xiàn)的開始位置

2. 使用空格將相同的變量桶唐、屬性對齊,使用換行分組

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茉兰,一起剝皮案震驚了整個(gè)濱河市莽红,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌邦邦,老刑警劉巖安吁,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異燃辖,居然都是意外死亡鬼店,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門黔龟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妇智,“玉大人,你說我怎么就攤上這事氏身∥±猓” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵蛋欣,是天一觀的道長航徙。 經(jīng)常有香客問我,道長陷虎,這世上最難降的妖魔是什么到踏? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任杠袱,我火速辦了婚禮,結(jié)果婚禮上窝稿,老公的妹妹穿的比我還像新娘楣富。我一直安慰自己,他們只是感情好伴榔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布纹蝴。 她就那樣靜靜地躺著,像睡著了一般踪少。 火紅的嫁衣襯著肌膚如雪骗灶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天秉馏,我揣著相機(jī)與錄音耙旦,去河邊找鬼。 笑死萝究,一個(gè)胖子當(dāng)著我的面吹牛免都,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播帆竹,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼绕娘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了栽连?” 一聲冷哼從身側(cè)響起险领,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秒紧,沒想到半個(gè)月后绢陌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熔恢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年脐湾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叙淌。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秤掌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鹰霍,到底是詐尸還是另有隱情闻鉴,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布茂洒,位于F島的核電站孟岛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚀苛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一在验、第九天 我趴在偏房一處隱蔽的房頂上張望玷氏。 院中可真熱鬧堵未,春花似錦、人聲如沸盏触。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赞辩。三九已至雌芽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辨嗽,已是汗流浹背世落。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糟需,地道東北人屉佳。 一個(gè)月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像洲押,于是被迫代替她去往敵國和親武花。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容

  • iOS編程規(guī)范0規(guī)范 0.1前言 為??高產(chǎn)品代碼質(zhì)量,指導(dǎo)廣大軟件開發(fā)人員編寫出簡潔杈帐、可維護(hù)体箕、可靠、可 測試挑童、高效...
    iOS行者閱讀 4,446評論 21 35
  • 37.cocoa內(nèi)存管理規(guī)則 1)當(dāng)你使用new累铅,alloc或copy方法創(chuàng)建一個(gè)對象時(shí),該對象的保留計(jì)數(shù)器值為1...
    如風(fēng)家的秘密閱讀 838評論 0 4
  • 推薦文章:禪與 Objective-C 編程藝 前言 為??高產(chǎn)品代碼質(zhì)量,指導(dǎo)廣大軟件開發(fā)人員編寫出簡潔站叼、可維護(hù)争群、...
    WolfTin閱讀 2,755評論 0 1
  • 1.項(xiàng)目經(jīng)驗(yàn) 2.基礎(chǔ)問題 3.指南認(rèn)識 4.解決思路 ios開發(fā)三大塊: 1.Oc基礎(chǔ) 2.CocoaTouch...
    陽光的大男孩兒閱讀 4,971評論 0 13
  • 1.1 什么是自動(dòng)引用計(jì)數(shù) 概念:在 LLVM 編譯器中設(shè)置 ARC(Automaitc Reference Co...
    __silhouette閱讀 5,120評論 1 17