翻譯自“Coding Guidelines for Cocoa”
0 簡(jiǎn)介
使用公開(kāi)的API開(kāi)發(fā)一個(gè)Cocoa框架,插件,或者其它可執(zhí)行文件需要的方法和規(guī)范,跟開(kāi)發(fā)應(yīng)用程序的不一樣。產(chǎn)品的主要用戶是開(kāi)發(fā)者,他們不會(huì)被編程接口迷惑。此時(shí)API的命名規(guī)范就派上了用場(chǎng),它們讓接口保持清晰和一致性。同時(shí)它們也是編程技術(shù),尤其對(duì)框架,例如版本控制,二進(jìn)制兼容性,錯(cuò)誤處理和內(nèi)存管理。這個(gè)專題同時(shí)包括Cocoa命名規(guī)范和推薦的框架編程實(shí)踐。
0.1 文檔結(jié)構(gòu)
本專題的文章分為兩類。第一類是編程接口的命名規(guī)范。這些規(guī)范與Apple自己的Cocoa框架一樣(有一些小的區(qū)別)。下面是命名規(guī)范的文章:
代碼命名基礎(chǔ)
方法命名
函數(shù)命名
屬性和數(shù)據(jù)類型命名
可接受的縮寫和首字母縮寫
第二部分討論框架編程相關(guān)的規(guī)范。
框架開(kāi)發(fā)者的技巧和技術(shù)
1 代碼命名基礎(chǔ)
設(shè)計(jì)面向?qū)ο筌浖?kù)時(shí),類,協(xié)議,方法,函數(shù),常量,以及其它元素的命名經(jīng)常被忽略。這一節(jié)討論大部分Cocoa接口的命名規(guī)范。
1.1 一般性原則
清晰
- 盡可能同時(shí)保持清晰和簡(jiǎn)潔,但不要因?yàn)楹?jiǎn)潔而犧牲清晰:
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| insertObject:atIndex: | 好 |
| insert:at: | 不清晰;插入什么?“at”表示什么? |
| removeObjectAtIndex: | 好 |
| removeObject: | 好,因?yàn)閰?shù)指定了要移除的對(duì)象 |
| remove | 不清晰;要移除什么? |
- 通常不要使用名字的縮寫。即使名字很長(zhǎng),也要拼寫完全:
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| destinationSelection | 好 |
| destSel | 不清晰 |
| setBackgroundColor: | 好 |
| setBkgdColor: | 不清晰 |
你可能會(huì)認(rèn)為某個(gè)縮寫廣為人知,但可能并非如此,尤其是當(dāng)方法或函數(shù)名被不同文化和語(yǔ)言背景的開(kāi)發(fā)人員使用時(shí)。
可以使用少數(shù)非常常見(jiàn)和歷史悠久的縮寫。參考“可接受的縮寫和首字母縮寫”一節(jié)。
避免使用有歧義的API名稱,例如有多個(gè)解釋的方法名。
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| sendPort | 發(fā)送端口還是返回一個(gè)發(fā)送端口? |
| displayName | 顯示名稱還是返回用戶界面中接收者的標(biāo)題? |
一致性
盡可能使用與Cocoa編程接口一致的名稱。如果不確定某個(gè)命名,請(qǐng)瀏覽當(dāng)前的頭文件或參考文件中的范例。
當(dāng)類的方法使用多態(tài)時(shí),一致性尤其重要。不同類中實(shí)現(xiàn)相同功能的方法應(yīng)該有相同的名稱。
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| - (NSInteger)tag | 在NSView, NSCell, NSControl中有定義 |
| *- (void)setStringValue:(NSString ) | 在許多Cocoa類中有定義 |
參考“方法參數(shù)”一節(jié)。
不要自我參考
- 名稱不應(yīng)該自我參考。
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| NSString | 可以 |
| NSStringObject | 自我參考 |
- 掩碼(可使用位操作進(jìn)行組合)和用于通知名稱的常量不受該約定限制。
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| NSUnderlineByWordMask | 可以 |
| NSTableViewColumnDidMoveNotification | 可以 |
1.2 前綴
前綴是名稱的重要組成部分。它們可以區(qū)分軟件的功能范圍。通常,軟件被打包成一個(gè)框架,或者多個(gè)緊密關(guān)聯(lián)的框架(如Foundation和Application Kit框架)。前綴可以防止第三方開(kāi)發(fā)者與Apple之間符號(hào)的命名沖突(也可以防止Apple內(nèi)部不同框架之間的沖突)。
- 前綴有規(guī)定的格式。它由兩到三個(gè)大寫字母組成,不能使用下劃線和子前綴。如下所示:
| 前綴 | Cocoa框架 |
|---|---|
| NS | Foundation |
| NS | Application Kit |
| AB | Address Book |
| IB | Interface Builder |
- 命名類,協(xié)議,函數(shù),常量和結(jié)構(gòu)體時(shí)使用前綴。命名成員方法時(shí)不使用前綴,因?yàn)榉椒ㄒ呀?jīng)在定義它的類的命名空間中。同樣的,不使用前綴命名結(jié)構(gòu)體的字段。
1.3 書(shū)寫規(guī)范
為API元素命名時(shí),遵循以下簡(jiǎn)單的書(shū)寫規(guī)范:
- 對(duì)于多個(gè)單詞組成的名稱,不要使用標(biāo)點(diǎn)符號(hào)作為名稱的一部分或者分隔符(下劃線,破折號(hào)等等);相反,應(yīng)該大寫每個(gè)單詞的首字母,并將單詞聯(lián)系拼寫(例如,runTheWorldsTogether)——即駝峰式命名。請(qǐng)注意以下限制:
- 方法名的首字母小寫,之后每個(gè)單詞的首字母大寫。不要使用前綴。
fileExistsAtPath:isDirectory:
該規(guī)則的一個(gè)例外是方法名以一個(gè)廣為人知的縮寫開(kāi)頭,例如:TIFFRepresentation (NSImage)。
- 函數(shù)名和常量名使用與其關(guān)聯(lián)類相同的前綴,并大寫每個(gè)單詞的首字母。
NSRunAlertPanel
NSCellDisabled
- 避免在方法名中使用下劃線作為前綴來(lái)表示私有方法(可以在實(shí)例變量名中使用下劃線作為前綴)。Apple保留了該規(guī)范的使用。如果第三方這樣使用,可能會(huì)導(dǎo)致命名空間沖突;他們可能無(wú)意的用自己的方法覆蓋了已經(jīng)存在的私有方法,這會(huì)導(dǎo)致嚴(yán)重的后果。請(qǐng)參考“私有方法”一節(jié)。
1.4 類和協(xié)議的名字
類名應(yīng)該包含一個(gè)明確描述類(或類的對(duì)象)是什么或者做什么的名詞。類名要有一個(gè)合適的前綴(參考“前綴”一節(jié))。Foundation和Application Kit框架很多這樣的例子,例如NSString,NSDate,NSScanner,NSApplication,UIApplication,NSButton,UIButton。
協(xié)議應(yīng)該根據(jù)如何分組行為來(lái)命名:
- 大部分協(xié)議組合相關(guān)的方法,而不關(guān)聯(lián)任何具體的類。這種類型的協(xié)議名稱不要與類名混淆。通常使用動(dòng)名詞("...ing")的格式:
| 代碼 | 點(diǎn)評(píng) |
|---|---|
| NSLocking | 好 |
| NSLock | 不好(像類名) |
- 有些協(xié)議組合一些不相關(guān)的方法(而不是創(chuàng)建多個(gè)獨(dú)立的小協(xié)議)。這些協(xié)議傾向于與某個(gè)類關(guān)聯(lián),該類是協(xié)議的主要體現(xiàn)者。這種情況下,協(xié)議名稱與類名一樣。
NSObject協(xié)議就是這樣一個(gè)例子。該協(xié)議組合不相關(guān)的方法,包括查詢對(duì)象在類繼承關(guān)系中位置的方法,調(diào)用特殊方法的方法,增加或減少引用計(jì)數(shù)的方法。因?yàn)?em>NSObject類是這些方法的主要體現(xiàn)者,所以用類名命名這個(gè)協(xié)議。
1.5 頭文件
如何命名頭文件很重要,因?yàn)槭褂玫拿?guī)范表明了頭文件的內(nèi)容。
- 聲明獨(dú)立的協(xié)議或類。如果類或協(xié)議不是分組的一部分,把它的聲明放在單獨(dú)的文件中,名稱與類或協(xié)議相同。
| 頭文件 | 聲明 |
|---|---|
| NSLocale.h | NSLocale類 |
- 聲明相關(guān)的類和協(xié)議。對(duì)于一組相關(guān)的聲明(類,類別和協(xié)議),把聲明放在一個(gè)文件中,文件名為主要的類,類別或協(xié)議。
| 頭文件 | 聲明 |
|---|---|
| NSString.h | NSString和NSMutableString類 |
| NSLock.h | NSLocking協(xié)議和NSLock,NSConditionLock,NSRecursiveLock類 |
包括框架頭文件。每個(gè)框架應(yīng)該有一個(gè)與框架同名的頭文件,其中包括該框架所有公開(kāi)的頭文件。
添加API到另一個(gè)框架中的類。如果在框架中聲明的方法是另一個(gè)框架中某個(gè)類的類別,在原類名后添加“Additions”;例如Application Kit中的NSBundleAdditions.h頭文件。
相關(guān)的函數(shù)和數(shù)據(jù)類型。講相關(guān)的函數(shù),常量,結(jié)構(gòu)體,以及其它數(shù)據(jù)類型放在同一個(gè)頭文件中,并以合適的名字命名,例如NSGraphics.h(Application Kit)。
2 方法命名
方法可能是編程接口中最常見(jiàn)的元素,因此要非常小心的為它們命名。本節(jié)討論方法命名的以下幾個(gè)方法:
2.1 一般性規(guī)則
為方法命名時(shí),記住以下一般性指南:
第一個(gè)單詞的首字母小寫,之后的每個(gè)單詞的首字母大寫。不要使用前綴。請(qǐng)參考“書(shū)寫規(guī)范”。
有兩種例外情況:第一,使用廣為人知的大寫字母縮寫命名方法(例如TIFF或PDF);第二,使用前綴分組和確定私有方法(參考“私有方法”)。表示對(duì)象行為的方法,以動(dòng)詞開(kāi)頭:
- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem
不要使用“do”或“does”作為名稱的一部分,因?yàn)檫@些助動(dòng)詞沒(méi)有實(shí)際意義。同樣的,動(dòng)詞之前不要使用副詞或形容詞。
- 如果方法返回接收者的某個(gè)屬性,直接用屬性名命名。不要使用“get”,除非間接返回一個(gè)或多個(gè)值。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (NSSize)cellSize; | 正確 |
| - (NSSize)calcCellSize; | 錯(cuò)誤 |
| - (NSSize)getCellSize; | 錯(cuò)誤 |
請(qǐng)參考“訪問(wèn)方法”一節(jié)。
- 在所有參數(shù)之前使用關(guān)鍵字。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag; | 正確 |
| - (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; | 錯(cuò)誤 |
- 參數(shù)之前的單詞要能描述該參數(shù)。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (id)viewWithTag:(NSInteger)aTag; | 正確 |
| - (id)taggedView:(int)aTag; | 錯(cuò)誤 |
- 當(dāng)創(chuàng)建的方法比繼承的方法更具體時(shí),在已存在的方法后添加新的關(guān)鍵字。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (id)initWithFrame:(CGRect)frameRect; | NSView,UIView |
| - (id)initWithFrame:(NSRect)frameRect mode:(int)aMode cellClass:(Class)factoryId numberOfRows:(int)rowsHigh numberOfColumns:(int)colsWide; | NSMatrix,NSView的子類 |
- 不要使用“and“連接關(guān)鍵字,該關(guān)鍵字是接收者的屬性。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; | 正確 |
| - (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; | 錯(cuò)誤 |
雖然上面的例子中使用”and“看起來(lái)不錯(cuò),但當(dāng)方法有更多關(guān)鍵字時(shí)就會(huì)有問(wèn)題。
- 當(dāng)方法描述兩個(gè)獨(dú)立的行為時(shí),用”and“連接它們。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| *- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString )appName andDeactivate:(BOOL)flag; | NSWorkspace |
2.2 訪問(wèn)方法
訪問(wèn)方法是對(duì)象屬性的讀取和設(shè)置方法,其命名的特定推薦格式依賴于如何描述屬性:
- 如果用名詞描述屬性,格式為:
- (type)noun;
- (void)setNoun:(type)aNoun;
例如:
- (NSString *)title;
- (void)setTitle:(NSString *)aTitle;
- 如果用形容詞描述屬性,格式為:
- (BOOL)isAdjective;
- (void)setAdjective:(BOOL)flag;
例如:
- (BOOL)isEditable;
- (void)setEditable:(BOOL)flag;
- 如果用動(dòng)詞描述屬性,格式為:(動(dòng)詞要使用一般現(xiàn)在時(shí))
- (BOOL)verbObject;
- (void)setVerbObject:(BOOL)flag;
例如:
- (BOOL)showsAlpha;
- (void)setShowsAlpha:(BOOL)flag;
- 不要把動(dòng)詞的分詞形式作為形容詞使用:
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (void)setAcceptsGlyphInfo:(BOOL)flag; | 正確 |
| - (BOOL)acceptsGlyphInfo; | 正確 |
| - (void)setGlyphInfoAccepted:(BOOL)flag; | 錯(cuò)誤 |
| - (BOOL)glyphInfoAccepted; | 錯(cuò)誤 |
- 可以使用情態(tài)動(dòng)詞(can,should,will等)明確意圖,但不要使用”do“或”does“。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| - (void)setCanHide:(BOOL)flag; | 正確 |
| - (BOOL)canHide; | 正確 |
| - (void)setShouldCloseDocument:(BOOL)flag; | 正確 |
| - (BOOL)shouldCloseDocument; | 正確 |
| - (void)setDoesAcceptGlyphInfo:(BOOL)flag; | 錯(cuò)誤 |
| - (BOOL)doesAcceptGlyphInfo; | 錯(cuò)誤 |
- 只在方法簡(jiǎn)介返回對(duì)象和值時(shí)使用”get“。當(dāng)需要返回多個(gè)項(xiàng)時(shí)才使用這種格式的方法。
| 方法名 | 點(diǎn)評(píng) |
|---|---|
| *- (void)getLineDash:(float *)pattern count:(int *)count phase:(float )phase; | NSBezierPath |
像上面這樣的方法,實(shí)現(xiàn)時(shí)應(yīng)該允許接收NULL作為in/out參數(shù),表示調(diào)用者不需要一個(gè)或多個(gè)返回值。
2.3 代理方法
特定事件發(fā)生時(shí),對(duì)象在其代理中(如果代理實(shí)現(xiàn)了代理方法)調(diào)用代理方法。它們有獨(dú)特的格式,同樣也適用于對(duì)象的數(shù)據(jù)源方法。
- 以發(fā)送消息的對(duì)象的類名開(kāi)頭,省略類的前綴,并小寫第一個(gè)字母:
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
- 冒號(hào)緊跟在類名之后(參數(shù)是被代理對(duì)象的引用),除非該方法只有一個(gè)”sender“參數(shù)。
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
- 作為響應(yīng)通知結(jié)果的方法是一個(gè)例外,此時(shí)唯一的參數(shù)是通知對(duì)象。
- (void)windowDidChangeScreen:(NSNotification *)notification;
- 通知代理對(duì)象操作已經(jīng)發(fā)生或即將發(fā)生的方法使用“did”或“will”。
- (void)browserDidScroll:(NSBrowser *)sender;
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;
- 詢問(wèn)代理對(duì)象能否執(zhí)行某個(gè)操作可以使用“did”或“will”,但最好使用“should”。
- (BOOL)windowShouldClose:(id)sender;
2.4 集合方法
管理對(duì)象集合的對(duì)象(集合中的對(duì)象叫做元素)方法具備如下的格式:
- (void)addElement:(elementType)anObj;
- (void)removeElement:(elementType)anObj;
- (NSArray *)elements;
例如:
- (void)addLayoutManager:(NSLayoutManager *)obj;
- (void)removeLayoutManager:(NSLayoutManager *)obj;
- (NSArray *)layoutManagers;
下面是集合方法命名的一些限制和規(guī)定:
如果集合是無(wú)序的,返回NSSet對(duì)象,而不是NSArray對(duì)象。
如果在指定位置插入元素的功能很重要,使用類似下面的方法代替或者添加到上面的規(guī)范中:
- (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index;
- (void)removeLayoutManagerAtIndex:(int)index;
集合方法的實(shí)現(xiàn)需要考慮以下細(xì)節(jié):
這些方法通常擁有插入對(duì)象,所以添加或插入的代碼需要retain元素,并在移除的代碼中release元素。
如果被插入的對(duì)象需要主對(duì)象的指針時(shí),通常使用set...方法設(shè)置該指針,并且不要retain。在insertLayoutManager:atIndex:方法中,NSLayoutManager類使用如下方法:
- (void)setTextStorage:(NSTextStorage *)textStorage;
- (NSTextStorage *)textStorage;
通常不會(huì)直接調(diào)用setTextStorage:方法,而是覆寫它。
另一個(gè)關(guān)于上面集合方法規(guī)范的例子是NSWindow類:
- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
- (void)removeChildWindow:(NSWindow *)childWin;
- (NSArray *)childWindows;
- (NSWindow *)parentWindow;
- (void)setParentWindow:(NSWindow *)window;
2.5 方法參數(shù)
命名方法參數(shù)需要考慮以下一般性規(guī)則:
與方法名一樣,參數(shù)名的第一個(gè)單詞的首字母小寫,之后的每個(gè)單詞的首字母大寫(例如:removeObject:(id)anObject)。
不要在名稱中使用pointer或ptr。用參數(shù)的類型,而不是名稱聲明是否是指針。
避免使用one-,two-letter作為參數(shù)名。
避免少寫幾個(gè)字符而使用縮寫。
按慣例(在Cocoa中),結(jié)合使用下面的關(guān)鍵字和參數(shù):
...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
2.6 私有方法
大多數(shù)情況下,私有方法的命名與公共方法命名的規(guī)范相同。但通常給私有方法加一個(gè)前綴,以便與公共方法區(qū)分開(kāi)來(lái)。即使在這個(gè)規(guī)范下,私有方法名還是會(huì)導(dǎo)致奇怪的問(wèn)題。設(shè)計(jì)一個(gè)從Cocoa框架繼承的子類時(shí),不知道自己的私有方法是否無(wú)意的覆蓋了框架中同名的私有方法。
Cocoa框架中大部分私有方法名使用下劃線(例如:_fooData)標(biāo)志為私有的。因此遵循下面兩條建議:
不要使用下劃線作為私有方法的前綴,Apple保留了這個(gè)規(guī)范。
如果繼承Cocoa框架中的一個(gè)超大類(例如:NSView或UIView),并想要完全區(qū)分父類私有方法和自己的私有方法,可以為私有方法添加自己的前綴。這個(gè)前綴應(yīng)該盡可能唯一,例如基于公司或工程的名稱,如“XX_”這樣的格式。如果工程名是“Byte Flogger”,前綴可以是“BF_addObject:”。
盡管為私有方法添加前綴的建議與之前為方法命名的規(guī)范自相矛盾,但這里的目的不一樣:防止無(wú)意覆寫父類中的私有方法。
3 函數(shù)命名
Objective-C允許使用函數(shù)描述行為,如同方法一樣。當(dāng)對(duì)象是單例時(shí),或者處理明顯的函數(shù)式子系統(tǒng)時(shí),應(yīng)該使用函數(shù)而不是類方法。
函數(shù)命名應(yīng)該遵循如下一般性的規(guī)則:
- 函數(shù)名與方法名類似,但有幾點(diǎn)不同:
- 它們以與類和常量相同的前綴開(kāi)頭。
- 前綴之后的第一個(gè)單詞的首字母大寫。
- 大部分函數(shù)以動(dòng)詞開(kāi)頭,描述該函數(shù)的行為:
NSHighlightRect
NSDeallocateObject
查詢屬性的函數(shù)有更多的命名規(guī)則:
- 如果函數(shù)返回第一個(gè)參數(shù)的屬性,省略動(dòng)詞。
unsigned int NSEventMaskFromType(NSEventType type)
float NSHeight(NSRect aRect)
- 如果通過(guò)引用返回值,使用“Get”。
const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsigned int *alignp)
- 如果返回值是boolean類型,函數(shù)用判斷動(dòng)詞開(kāi)頭。
BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)
4 屬性和數(shù)據(jù)類型命名
本節(jié)描述聲明屬性,實(shí)例變量,常量,通知和異常的命名規(guī)范。
4.1 聲明屬性和實(shí)例變量
一個(gè)聲明的屬性實(shí)際上聲明了屬性的一個(gè)訪問(wèn)方法,因此屬性的命名規(guī)范大體上與訪問(wèn)方法相同(參考“訪問(wèn)方法”)。如果屬性用名稱或動(dòng)詞描述,格式為:
@property (…) type nounOrVerb;
例如:
@property (strong) NSString *title;
@property (assign) BOOL showsAlpha;
如果屬性用形容詞描述,省略“is”前綴,但指明get訪問(wèn)器的規(guī)范的名稱,例如:
@property (assign, getter=isEditable) BOOL editable;
多數(shù)情況下,使用一個(gè)聲明的屬性時(shí),同時(shí)生成了一個(gè)相應(yīng)的實(shí)例變量。
確保實(shí)例變量簡(jiǎn)明扼要的描述了存儲(chǔ)的屬性。通常不直接訪問(wèn)實(shí)例變量,而是使用訪問(wèn)方法(在init和dealloc方法中直接訪問(wèn)實(shí)例變量)。為了達(dá)到這個(gè)目的,在實(shí)例變量名之前添加下劃線作為前置,例如:
@implementation MyClass {
BOOL _showsTitle;
}
如果使用一個(gè)生命的屬性生成實(shí)例變量,在@synthesize中指定實(shí)例變量的名稱。
@implementation MyClass
@synthesize showsTitle=_showsTitle;
為類添加實(shí)例變量時(shí)需要考慮以下幾個(gè)方面:
避免顯式的聲明public實(shí)例變量。
開(kāi)發(fā)者應(yīng)該關(guān)注對(duì)象的接口,而不是如何存儲(chǔ)數(shù)據(jù)的細(xì)節(jié)。通過(guò)聲明屬性和生成相應(yīng)的實(shí)例變量避免顯式的聲明實(shí)例變量。如果需要聲明實(shí)例變量,用@private或@protected顯式的聲明。
如果希望類被繼承,并且子類需要直接訪問(wèn)數(shù)據(jù),使用@protected。如果實(shí)例變量是類實(shí)例的可訪問(wèn)屬性,確保使用訪問(wèn)方法(盡可能使用聲明的屬性)。
4.2 常量
常量命名規(guī)則根據(jù)創(chuàng)建方式的不同而大不相同。
4.2.1 枚舉常量
使用枚舉定義一組相關(guān)的整數(shù)常量。
枚舉常量與其typedef命名遵循函數(shù)的命名規(guī)范(參考“函數(shù)命名”)。
下面的例子來(lái)自NSMatrix.h。本例中typedef標(biāo)識(shí)(_NSMatrixMode)不是必須的。
typedef enum _NSMatrixMode {
NSRadioModeMatrix = 0,
NSHighlightModeMatrix = 1,
NSListModeMatrix = 2,
NSTrackModeMatrix = 3
} NSMatrixMode;
- 可以創(chuàng)建不具名枚舉,比如位掩碼。
enum {
NSBorderlessWindowMask = 0,
NSTitledWindowMask = 1 << 0,
NSClosableWindowMask = 1 << 1,
NSMiniaturizableWindowMask = 1 << 2,
NSResizableWindowMask = 1 << 3
};
4.2.2 使用const創(chuàng)建的常量
使用const創(chuàng)建浮點(diǎn)常量。如果常量與其它常量不相關(guān),可以使用const創(chuàng)建整數(shù)常量;否則使用枚舉。
const常量格式如下面的聲明所示:
const float NSLightGray;
枚舉常量的命名規(guī)范跟函數(shù)命名規(guī)范相同。
4.2.3 其它類型的常量
通常不適用#define預(yù)處理命令創(chuàng)建常量。對(duì)于整數(shù)常量,使用枚舉,浮點(diǎn)數(shù)常量使用const。
使用大寫字母定義預(yù)處理宏,來(lái)決定代碼塊是否執(zhí)行。例如:
#ifdef DEBUG
- 編譯器定義的宏的頭尾都有雙下劃線,例如:
__MACH__
- 定義常量字符串用作通知名和字典的鍵。使用常量字符串,編譯器可以執(zhí)行拼寫檢查。Cocoa框架提供了很多常量字符串的例子:
APPKIT_EXTERN NSString *NSPrintCopies;
字符串在實(shí)現(xiàn)文件中賦值。(注意:APPKIT_EXTERN宏在Objective-C中等價(jià)于extern)
4.3 通知和異常
通知和異常的命名遵循相似的規(guī)則,但它們有各自的推薦使用模式。
4.3.1 通知
如果一個(gè)類有代理,那它的大部分通知可能由代理類的代理方法接收。這些通知的名稱應(yīng)該能夠反應(yīng)對(duì)應(yīng)的代理方法。例如,當(dāng)應(yīng)用程序提交NSApplicationDidBecomeActiveNotification通知時(shí),全局的NSApplication對(duì)象的代理自動(dòng)注冊(cè)接收applicationDidBecomeActive:消息。
通知由如下形式的全局NSString對(duì)象標(biāo)識(shí):
[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification
例如:
NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification
NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification
4.3.2 異常
雖然可以因?yàn)槿魏文康亩褂卯惓#ㄓ蒒SException類和相關(guān)函數(shù)實(shí)現(xiàn)),但Cocoa使用異常來(lái)處理類似數(shù)組越界的編程錯(cuò)誤。Cocoa不適用異常處理常規(guī)的,可預(yù)料的錯(cuò)誤。這些情況下,使用nil,NULL,NO,或錯(cuò)誤代碼之類的返回值。
異常由如下形式的全局NSString對(duì)象標(biāo)識(shí):
[Prefix] + [UniquePartOfName] + Exception
名稱的唯一部分(UniquePartOfName)部分由單詞組成,每個(gè)單詞的第一個(gè)字母大寫。例如:
NSColorListIOException
NSColorListNotEditableException
NSDraggingException
NSFontUnavailableException
NSIllegalSelectorException
5 可接受的縮寫和首字母縮寫
設(shè)計(jì)編程接口時(shí),通常不使用縮寫(參考“一般性規(guī)則”)。然后下面列出的縮寫要么是相沿成習(xí),要么是過(guò)去廣泛使用的,所以可以繼續(xù)使用。關(guān)于縮寫有一些額外的注意事項(xiàng):
標(biāo)準(zhǔn)C庫(kù)中長(zhǎng)期使用的縮寫形式是可以接受的,例如:“alloc”,“getc”。
在參數(shù)名中可以更自由的使用縮寫,例如:“imageRep”,“col”(“column”),“obj”,“otherWin”。
| 縮寫 | 含義和注釋 |
|---|---|
| alloc | Allocate |
| app | Application。例如,全局application對(duì)象NSApp。但在代理方法,通知等中,應(yīng)該使用“application”全拼。 |
| alt | Alternate |
| calc | Calculate |
| dealloc | Deallocate |
| func | Function |
| horiz | Horizontal |
| info | Information |
| init | Initialize |
| int | Integer |
| max | Maximum |
| min | Minimum |
| msg | Message |
| nib | Interface Builder文件 |
| pboard | Pasteboard(只在常量中) |
| rect | Rectangle |
| Rep | Representation(在類名中使用,如NSBitmapImageRep) |
| temp | Temporary |
| vert | Vertical |
可以使用計(jì)算機(jī)行業(yè)的常見(jiàn)縮寫和首字母縮寫,例如:
ASCII
PDF
XML
HTML
URL
RTF
HTTP
TIFF
JPG
PNG
GIF
LZW
ROM
RGB
CMYK
MIDI
FTP
6 框架開(kāi)發(fā)者的小貼士和技術(shù)
沒(méi)有開(kāi)發(fā)框架,不敢隨便翻譯,以后有機(jī)會(huì)再翻譯。