iOS 編碼規(guī)范

注:本文轉(zhuǎn)載自http://www.cocoachina.com/ios/20150908/13335.html, 非作者原創(chuàng),用于個(gè)人隨時(shí)查閱,特此聲明!!!
簡(jiǎn)介:
本文整理自Apple文檔《Coding Guidelines for Cocoa》。這份文檔原意是給Cocoa框架、插件及公共API開發(fā)者提供一些編碼指導(dǎo),實(shí)質(zhì)上相當(dāng)于Apple內(nèi)部的編碼規(guī)范。在多人協(xié)作時(shí),一份統(tǒng)一的代碼規(guī)范大大減少開發(fā)者之間的溝通成本,極力推薦。
目錄:
一、代碼命名基礎(chǔ)
二、方法
三、函數(shù)
四、Property及其他
五、縮寫
一、代碼命名基礎(chǔ)
1.通用原則
1.1 清晰
盡量清晰又簡(jiǎn)潔,無法兩全時(shí)清晰更重要

1441509819955470.png

通常不應(yīng)縮寫名稱,即使方法名很長也應(yīng)完整拼寫
你可能認(rèn)為某個(gè)縮寫眾所周知,但其實(shí)未必,特別是你周圍的開發(fā)者語言文化背景不同時(shí)

有一些歷史悠久的縮寫還是可以使用的,詳見第五章

1441509896749042.png

API命名避免歧義,例如一個(gè)方法名有多種理解

1441509905881130.png

1.2 一致
盡力保持Cocoa編程接口命名一致
如果有疑惑,請(qǐng)瀏覽當(dāng)前頭文件或者參考文檔

當(dāng)某個(gè)類的方法使用了多態(tài)時(shí),一致性尤其重要
不同類里,功能相同的方法命名也應(yīng)相同

1441509959926816.png

1.3 避免自引用(self Reference)
命名不應(yīng)自引用
這里的自引用指的是在詞尾引用自身

1441509975783777.png

Mask與Notification忽略此規(guī)則


1441509984966357.png

2.前綴
前綴是編程接口命名的重要部分,它們區(qū)分了軟件的不同功能區(qū)域:
前綴可以防止第三方開發(fā)者與Apple的命名沖突

同樣可以防止Apple內(nèi)部的命名沖突

前綴有指定格式

它由二到三個(gè)大寫字母組成,不使用下劃線和子前綴

命名類、協(xié)議、函數(shù)、常量和typedef結(jié)構(gòu)體時(shí)使用前綴

方法名不使用前綴(因?yàn)樗嬖谟谔囟惖拿臻g中)

結(jié)構(gòu)體字段不使用前綴


[圖片上傳中。。。(7)]
3.書寫約定
在命名API元素時(shí), 使用駝峰命名法(如runTheWordsTogether),并注意以下書寫約定:
方法名
小寫第一個(gè)字母,大寫之后所有單詞的首字母,不使用前綴

如果方法名以一個(gè)眾所周知的大寫縮略詞開始,該規(guī)則不適用

如TIFFRepresentation (NSImage)
1

fileExistsAtPath:isDirectory:

函數(shù)及常量名
使用與其關(guān)聯(lián)類相同的前綴,并大寫首字母

1
2

NSRunAlertPanel

NSCellDisabled

標(biāo)點(diǎn)符號(hào)
由多個(gè)單詞組成的名稱,別使用標(biāo)點(diǎn)符號(hào)作為名稱的一部分

分隔符(下劃線、破折號(hào)等)也不能使用

避免使用下劃線作為私有方法的前綴,Apple保留這一方式的使用

強(qiáng)行使用可能會(huì)導(dǎo)致命名沖突,即Apple已有的方法被覆蓋,這會(huì)導(dǎo)致災(zāi)難性后果

實(shí)例變量使用下劃線作為前綴還是允許的

4.class與protocol命名
class
class的名稱應(yīng)該包含一個(gè)名詞,用以表明這個(gè)類是什么(或者做了什么),并擁有合適的前綴

如NSString、NSDate、NSScanner、UIApplication、UIButton

不關(guān)聯(lián)class的protocol
大多數(shù)protocol聚集了一堆相關(guān)方法,并不關(guān)聯(lián)class

這種protocol使用ing形式以和class區(qū)分開來

1441510247983445.png

關(guān)聯(lián)class的protocol
一些protoco聚集了一堆無關(guān)方法,并試圖與某個(gè)class關(guān)聯(lián)在一起,由這個(gè)class來主導(dǎo)

這種protocol與class同名

如NSObject protocol

5.頭文件
頭文件的命名極其重要,因?yàn)樗梢灾赋鲱^文件包含的內(nèi)容:
聲明一個(gè)孤立的class或protocol

將聲明放入單獨(dú)的文件

使頭文件名與聲明的class/protocol相同

[圖片上傳中。。。(9)]
聲明關(guān)聯(lián)的class或protocol

將關(guān)聯(lián)的聲明(class/category/protocol)放入同一個(gè)頭文件

頭文件名與主要的class/category/protocol相同

[圖片上傳中。。。(10)]
Framework頭文件

每個(gè)framework都應(yīng)該有一個(gè)同名頭文件

Include了框架內(nèi)其他所有頭文件

1441510294801244.png

添加API到另一個(gè)framework

如果要在一個(gè)framework中為另一個(gè)framework的class catetgory添加方法,加上單詞“Additions”

如Application Kit的NSBundleAdditions.h 文件

關(guān)聯(lián)的函數(shù)、數(shù)據(jù)類型

如果你有一組關(guān)聯(lián)的函數(shù)、常量、結(jié)構(gòu)體或其他數(shù)據(jù)類型,將它們放到一個(gè)名字合適的頭文件中

如Application Kit的NSGraphics.h

二、方法
1.通用原則
以小寫字母開始,之后單詞的首字母大寫

以眾所周知的縮寫開始可以大寫,如TIFF、PDF

私有方法可以加前綴

如果方法代表對(duì)象接收的動(dòng)作,以動(dòng)詞開始

不要使用 do 或 does 作為名字的一部分,因?yàn)橹鷦?dòng)詞在這里很少有實(shí)際意義

同樣的,也別在動(dòng)詞之前使用副詞和形容詞

1
2

  • (void)invokeWithTarget:(id)target;

  • (void)selectTabViewItem:(NSTabViewItem *)tabViewItem

如果方法返回接收者的屬性,以 接收者 + 接收的屬性 命名

除非間接返回多個(gè)值,否則不要使用 get 單詞(為了與accessor methods區(qū)分)

[圖片上傳中。。。(12)]
在所有參數(shù)之前使用關(guān)鍵字
[圖片上傳中。。。(13)]
確保參數(shù)之前的關(guān)鍵字充分描述了參數(shù)
[圖片上傳中。。。(14)]
創(chuàng)建自定義 init 方法時(shí),記得指明關(guān)聯(lián)的元素
[圖片上傳中。。。(15)]
不要使用 and 來連接作為接收者屬性的關(guān)鍵字
雖然下面的例子使用 and 看似不錯(cuò),但是一旦參數(shù)非常多時(shí)就容易出現(xiàn)問題

[圖片上傳中。。。(16)]
除非方法描述了兩個(gè)獨(dú)立的操作,才使用 and 來連接它們
[圖片上傳中。。。(17)]
2.getter和setter方法(Accessor Methods)
如果property表示為名詞,格式如下

  • (type)noun;

  • (void)setNoun:(type)aNoun;

  • (BOOL)isAdjective;

1
2

  • (NSString *)title;

  • (void)setTitle:(NSString *)aTitle;

如果property表示為形容詞,格式如下

  • (BOOL)isAdjective;

  • (void)setAdjective:(BOOL)flag;

1
2

  • (BOOL)isEditable;

  • (void)setEditable:(BOOL)flag;

如果property表示為動(dòng)詞,格式如下(動(dòng)詞用一般現(xiàn)在時(shí))

  • (BOOL)verbObject;

  • (void)setVerbObject:(BOOL)flag;

1
2

  • (BOOL)showsAlpha;

  • (void)setShowsAlpha:(BOOL)flag;

不要把動(dòng)詞的過去分詞形式當(dāng)作形容詞使用
[圖片上傳中。。。(18)]
你可能使用情態(tài)動(dòng)詞(can、should、will等)來增加可讀性,不過不要使用 do或 does
[圖片上傳中。。。(19)]
只有方法需要間接返回多個(gè)值的情況下才使用 get
像這種接收多個(gè)參數(shù)的方法應(yīng)該能夠傳入nil,因?yàn)檎{(diào)用者未必對(duì)每個(gè)參數(shù)都感興趣
[圖片上傳中。。。(20)]
3.Delegate方法
以發(fā)送消息的對(duì)象開始
省略了前綴的類名和首字母小寫
1
2

  • (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;

  • (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;

以發(fā)送消息的對(duì)象開始的規(guī)則不適用下列兩種情況
只有一個(gè)sender參數(shù)的方法
1

  • (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;

響應(yīng)notification的方法(方法的唯一參數(shù)就是notification)
1

  • (void)windowDidChangeScreen:(NSNotification *)notification;

使用單詞 did 和 will 來通知delegate
did 表示某些事已發(fā)生

will 表示某些事將要發(fā)生

1
2

  • (void)browserDidScroll:(NSBrowser *)sender;

  • (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;

詢問delegate是否可以執(zhí)行某個(gè)行為時(shí)可以使用 did 或 will,不過 should 更完美
1

  • (BOOL)windowShouldClose:(id)sender;

**4.集合方法 **
為了管理集合中的元素,集合應(yīng)該有這幾個(gè)方法

  • (void)addElement:(elementType)anObj;

  • (void)removeElement:(elementType)anObj;

  • (NSArray *)elements;

1
2
3

  • (void)addLayoutManager:(NSLayoutManager *)obj;

  • (void)removeLayoutManager:(NSLayoutManager *)obj;

  • (NSArray *)layoutManagers;

如果集合是無序的,返回一個(gè)NSSet比NSarray更好
如果需要在集合中的特定位置插入元素,使用類似下面的方法
1
2

  • (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index;

  • (void)removeLayoutManagerAtIndex:(int)index;

其他集合方法示例
1
2
3
4
5

  • (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;

  • (void)removeChildWindow:(NSWindow *)childWin;

  • (NSArray *)childWindows;

  • (NSWindow *)parentWindow;

  • (void)setParentWindow:(NSWindow *)window;

**5.方法參數(shù) **
參數(shù)名以小寫字母開始,之后的單詞首字母大寫

1

如:removeObject:(id)anObject

別使用 ”pointer” 或 ”ptr” 命名

參數(shù)類型里就已表明它是否是一個(gè)指針

避免只有一到二個(gè)字母的參數(shù)名

避免只有幾個(gè)字母的縮寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

...action:(SEL)aSelector

...alignment:(int)mode

...atIndex:(int)index

...content:(NSRect)aRect

...doubleValue:(double)aDouble

...floatValue:(float)aFloat

...font:(NSFont *)fontObj

...frame:(NSRect)frameRect

...intValue:(int)anInt

...keyEquivalent:(NSString *)charCode

...length:(int)numBytes

...point:(NSPoint)aPoint

...stringValue:(NSString *)aString

...tag:(int)anInt

...target:(id)anObject

...title:(NSString *)aString

6.私有方法
不要使用下劃線作為私有方法的前綴,Apple保留這一使用方式
因?yàn)槿羰悄愕乃接蟹椒驯籄pple使用,覆蓋它將會(huì)產(chǎn)生極難追蹤的BUG
如果繼承自大型Cocoa框架(如UIView),請(qǐng)確保子類的私有方法名與父類不一樣
可以為私有方法加一個(gè)前綴,如公司名或項(xiàng)目名:XX_
例如你的項(xiàng)目叫做Byte Flogger,那么前綴可能是:BF_addObject
總之,為子類的私有方法添加前綴是為了不覆蓋其父類的私有方法
三、函數(shù)
函數(shù)的命名類似方法,但有兩點(diǎn)要注意
你使用的類和常量擁有相同的前綴

前綴后的首字母大寫

許多函數(shù)名以描述其作用的動(dòng)詞開始
1
2

NSHighlightRect

NSDeallocateObject

查詢屬性的函數(shù)有進(jìn)一步的命名規(guī)則
如果函數(shù)返回首個(gè)參數(shù)的屬性,省略動(dòng)詞
1
2

unsigned int NSEventMaskFromType(NSEventType type)

float NSHeight(NSRect aRect)

如果通過reference返回了值,使用 “Get”
1

const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsigned int *alignp)

如果返回的是boolean值,應(yīng)該靈活使用動(dòng)詞
1

BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)

四、Property及其他
1.Property與實(shí)例變量
1.1 Property
Property命名規(guī)則與第二章accessor methods一樣(因?yàn)閮烧呔o密聯(lián)系)
如果property表示為一個(gè)名詞或動(dòng)詞,格式如下
@property (…) 類型 名詞/動(dòng)詞 ;
1
2

@property (strong) NSString *title;

@property (assign) BOOL showsAlpha;

如果property表示為一個(gè)形容詞
可省略 ”is” 前綴

但要指定getter方法的慣用名稱

1

@property (assign, getter=isEditable) BOOL editable;

1.2 實(shí)例變量
通常不應(yīng)該直接訪問實(shí)例變量
init、dealloc、accessor methods等方法內(nèi)部例外
實(shí)例變量以下劃線 “_” 開始
確保實(shí)例變量描述了所存儲(chǔ)的屬性
1
2
3

@implementation MyClass {

BOOL _showsTitle;

}

如果想要修改property的實(shí)例變量名,使用 @synthesize語句
1
2

@implementation MyClass

@synthesize showsTitle=_showsTitle;

為一個(gè)class添加實(shí)例變量時(shí),有幾點(diǎn)需要注意:
避免聲明公有實(shí)例變量

開發(fā)者關(guān)注的應(yīng)該是對(duì)象接口,而不是其數(shù)據(jù)細(xì)節(jié)

你可以通過使用property來避免聲明實(shí)例變量

如果需要聲明實(shí)例變量,指定關(guān)鍵字@private 或 @protected

如果你希望子類可以直接訪問某個(gè)實(shí)例變量,使用 @protected 關(guān)鍵字

如果一個(gè)實(shí)例變量是某個(gè)類可訪問的屬性,確保寫了accessor methods

如果有可能,還是使用property

**2.常量 **
2.1 枚舉常量
使用枚舉來關(guān)聯(lián)一組integer常量
枚舉常量和typedef遵循函數(shù)的命名規(guī)范,下面的例子是 NSMatrix.h
1
2
3
4
5
6

typedef enum _NSMatrixMode {

NSRadioModeMatrix = 0,

NSHighlightModeMatrix = 1,

NSListModeMatrix = 2,

NSTrackModeMatrix = 3

} NSMatrixMode;

你可以為bit masks之類的東西創(chuàng)建一個(gè)匿名枚舉
1
2
3
4
5
6
7

enum {

NSBorderlessWindowMask = 0,

NSTitledWindowMask = 1 << 0,

NSClosableWindowMask = 1 << 1,

NSMiniaturizableWindowMask = 1 << 2,

NSResizableWindowMask = 1 << 3

};

**2.2 使用const關(guān)鍵字的常量 **
使用const關(guān)鍵字來創(chuàng)建一個(gè)float常量
你可以使用const關(guān)鍵字來創(chuàng)建一個(gè)與其他常量不相關(guān)的integer常量,否則,使用枚舉
使用const關(guān)鍵字的常量也遵循函數(shù)的命名規(guī)則
1

const float NSLightGray;

**2.3 其他常量類型 **
通常不應(yīng)使用 #define 預(yù)編譯指令來創(chuàng)建常量

integer常量,使用枚舉

float常量,使用 const 修飾符

對(duì) #define 預(yù)編譯指令,大寫所有字母

比如 DEBUG 判斷

1

ifdef DEBUG

注意宏命令的字首和字尾都有雙下劃線

1

MACH

定義NSString常量來作為Notification和Key值

這樣做可以有效防止拼寫錯(cuò)誤

1

APPKIT_EXTERN NSString *NSPrintCopies;

3.Notifications與Exceptions
**3.1 Notifications **
Notification的格式
1

[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification

1
2
3
4

NSApplicationDidBecomeActiveNotification

NSWindowDidMiniaturizeNotification

NSTextViewDidChangeSelectionNotification

NSColorPanelColorDidChangeNotification

**3.2 Exceptions **
Exception的格式

1

[Prefix] + [UniquePartOfName] + Exception

1
2
3
4
5

NSColorListIOException

NSColorListNotEditableException

NSDraggingException

NSFontUnavailableException

NSIllegalSelectorException

五、縮寫
設(shè)計(jì)編程接口時(shí)通常不應(yīng)使用縮寫,但下列已被廣泛使用的縮寫名稱除外
標(biāo)準(zhǔn)C庫中的縮寫名,如:alloc、init
參數(shù)名可自由使用縮寫,如:imageRep、col、obj、otherWin
[圖片上傳中。。。(21)]
[圖片上傳中。。。(22)]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 一.代碼命名 一般性原則 最好是既清晰又簡(jiǎn)短,但不要為簡(jiǎn)短而喪失清晰性。 例如:removeObject:AtIn...
    睡不完懶覺閱讀 1,799評(píng)論 0 16
  • Object-C 開發(fā)代碼規(guī)范概要Object-C是一門面向?qū)ο蟮膭?dòng)態(tài)編程語言,主要用于編寫IOS和MAC應(yīng)用程序...
    克魯?shù)吕?/span>閱讀 546評(píng)論 0 1
  • 以下所有純屬個(gè)人習(xí)慣,不喜勿噴 語言:應(yīng)該使用美國英語命名 如 UIColor *myColor = [UICol...
    夾娃娃達(dá)人閱讀 333評(píng)論 0 0
  • 面試被問到公司編碼規(guī)范問題,感覺有很多東西,但是不知道該怎么說出來,今天突然找到 李明杰 老師的一份編碼規(guī)范。重新...
    Dombo_Y閱讀 994評(píng)論 1 2
  • 今天本來準(zhǔn)備翻翻稻盛和夫的《活法》,突然看到友友送的一本《聰明人用方格筆記本》,順手翻開,竟被深深吸引了,書本內(nèi)容...
    上善若水999閱讀 247評(píng)論 2 1