Cocoa编程指南
這是一篇翻譯版,英文版來自apple的官方文檔:
Coding Guidelines for Cocoa
介紹
Cocoa編程指南介紹
通過公開API開發(fā)Cocoa框架,插件,或者其他可執(zhí)行文件需要一些不同于開發(fā)應用程序的方式和約定。開發(fā)者是你的產品的主要客戶,并且讓他們沒有對你的編程接口感到困惑是非常重要的。這就是API命名約定派上用場,這會有助于你的接口保持一致和清晰。還有些編程技術對于這個框架來說是比較特殊的或者說更加重要,例如版本控制,二進制兼容性,錯誤處理和內存管理。本專題包含Cocoa命名規(guī)范和推薦的框架編程實踐。
文檔組織結構
本專題所包含的文章分為兩類。第一部分和大部分的模塊給出了對編程接口的命名規(guī)范。apple在自身的Cocoa框架中也使用這些命名規(guī)范。這些關于命名規(guī)范的包含如下內容:
1. 代碼命名基礎 2. 方法的命名 3. 函數(shù)的命名 4. 屬性和數(shù)據(jù)類型的命名 5. 可接受的簡寫和縮寫第二部分(當前只有一個成員)討論框架開發(fā)的各個方面
框架開發(fā)的小技巧代碼命名基礎
類,方法,函數(shù),常量和其他編程接口的元素經常在面向對象編程軟件設計被忽視。該部分介紹了許多在cocoa接口中實現(xiàn)的命名規(guī)范。
基本原則
清晰
- 盡量保持清楚和簡潔很好,但是命名清晰比簡潔更重要。
| insertObject:atIndex: | 好 |
| insert:at: | 不清晰;插入什么?“at”表示什么?atNot clear;what is being inserted?what does “at”signify? |
| revmoveObjectAtIndext: | 好 |
| removeObject: | 好,因為刪除作為參數(shù)的對象。 |
| remove: | 不明確,刪除什么? |
- 通常,不要縮寫名字。即使它們很長也要拼寫出來。
| destinationSelection: | 好 |
| destSel | 不清晰 |
| setBackgroundColor: | 好 |
| setBkgColor: | 不清晰 |
你可能認為縮寫是眾所周知的,但它可能不是,特別是有不同的文化和語言背景開發(fā)者遇到你的方法和函數(shù)。
- 然而,有少數(shù)的縮寫確實是通用的并且用了很長時間。可以繼續(xù)使用,查看Acceptable Abbreviations and Acronyms.
- 避免API命名不明確,例如方法名稱可能被解釋為多種含義。
| sendPort | 是發(fā)送端口還是返回端口? |
| displayName | 在用戶界面中顯示一個名字還是返回接受者的標題 ? |
一致性
- 嘗試保持在Cocoa編程接口上的命名一致性。如果不確定,請查閱現(xiàn)在的頭文件或者之前的參看文件。
- 當一個類中的許多方法有多態(tài)性的時候,一致性是非常重要的。這些方法在不同的類中使用同樣的名稱做同樣的操作。
| 定義在NSView,NSCell,NSControl. |
| 在許多Cocoa類中有定義 |
也可參照:Method Arguments
不要自我引用
- 命名不應該自我引用
| NSString | 可以 |
| NSStringObject | 自我引用 |
- 作為掩碼的一些常量(可以按位與進行合并),這些常量常量一般不使用這種規(guī)則,例如作為通知名稱的常量.
| NSUnderlineByWordMask | 可以 |
| NSTableViewColumnDidMoveNotification | 可以 |
前綴
書寫約定
下面有幾個簡單的命名API的書寫規(guī)范
- 名字有多個單詞組成,不要使用下劃線,破折號或者其他符號分割。使用駝峰命名法
對于方法命名,以小寫字母開頭,后面的單詞首字母大寫。不要使用前綴。
- 函數(shù)和常量的命名,對于相關的類使用同樣的前綴并且首字母大寫以及后邊的單詞
- 避免使用下劃線作為前綴
類和協(xié)議的命名
類的名稱應該包含一個清晰的表達出該類的意義。類名應該有一個前綴。Foundation和許多應用程序框架都是一些案例。例如NSString,NSData,NSScanner,NSApplication …和UIButton。
Protocol 應該根據(jù)它所組成的一些行為事件來命名。
- 大多數(shù)的協(xié)議與包含的一些方法有關系而與某種類沒有關系。這種協(xié)議應該避免與類名混淆。通常約定用一種動名詞(“…ing”)的格式.
| NSLocking | 好 |
| NSLock | 差(看起來像一個類名) |
- 一些協(xié)議包含許多沒有關系的方法(而不是創(chuàng)建很多分離的小的協(xié)議)。這些協(xié)議與某個類有關系,這個類是這些協(xié)議的主要表現(xiàn)。在這種情況下,應該約定將協(xié)議和類命名一致。
NSObject協(xié)議就是這種類型的協(xié)議。
頭文件
方法命名
方法的命名也許是編程接口中最普通的元素,因此應該在命名過程中需要特別注意。這部分討論方法命名的如下幾個方面:
基本規(guī)則
通常有如下幾項規(guī)則:
- 小寫字母開頭,大寫包含的英文單詞的首字母。不要使用前綴
- 對于表示操作于某個對象的方法,方法的命名以動詞開頭:
不要使用“do” 或者 “does” 作為名字的一部分因為這些助動詞幾乎沒有任何意義。并且,不要在動詞前面使用副詞或者形容詞。
- 如果某個方法返回調用者的某個屬性,直接在屬性后面命名就可以。不要使用“get”,除非需要直接返回一個或者多個值。
| 正確 |
| 錯誤 |
| 錯誤 |
- 在參數(shù)前面使用關鍵字
| 正確 |
| 錯誤 |
- 在參數(shù)前面描述參數(shù)
| 正確 |
| 錯誤 |
- 當創(chuàng)建一個比繼承的方法更加明確的方法的時候,需要添加新的關鍵字在已經存在的方法后面。
| NSView, UIView. |
| NSMatrix, a subclass of NSView |
- 不要使用“and”連接是調用者屬性的關鍵字。
| 正確 |
| 錯誤 |
- 如果方法有兩種不同的行為,使用“and”連接它們。
| NSWorkspace |
訪問器方法
訪問器方法是一個設置和讀取對象的屬性值得方法。根據(jù)屬性的表達方式擁有某種推薦的方式。
- 一個屬性表示一個名詞,格式是:
舉例:
- (NSString *)title;- (void)setTitle:(NSString *)aTitle;- 一個屬性表示形容詞,格式是:
舉例:
- (BOOL)isEditable;- (void)setEditable:(BOOL)flag;- 屬性表示動詞,格式是:
舉例:
- (BOOL)showsAlpha;- (void)setShowsAlpha:(BOOL)flag;動詞應該使用現(xiàn)在時
- 不要將動詞通過介詞轉為形容詞
| 正確 |
| 正確 |
| 錯誤 |
| 錯誤 |
- 可以使用情態(tài)動詞(在動詞前面加 “can”,“should”,“will”等等)澄清含義,但是不要使用“do”或者“does”
| 正確 |
| 正確 |
| 正確 |
| 正確 |
| 錯誤 |
| 錯誤 |
- 只有在間接返回對象和值的方法中才使用“get”,只有需要返回多個值得的方法菜需要使用這種格式。
| NSBezierPath. |
代理方法
代理方法是對象能夠在其代理中喚醒調用當某種事件發(fā)生的時候。它們有一種特殊的形式,這種形式同樣適用于一個對象數(shù)據(jù)源的方法中。
- 以表示發(fā)送消息的對象所屬類來命名開頭
該類的名字省略了前綴并且以小寫字母開頭。
- 冒號在類名后面(對于代理對象來說參數(shù)是一個引用)除非方法只有一個參數(shù),這個參數(shù)就是消息發(fā)送者。
- 有一種例外就是消息通知發(fā)送的消息。這種情況下,唯一的參數(shù)是通知對象。
- 代理方法使用“did”或者“will”通知代理已經發(fā)生了或者將要發(fā)生什么?
- 盡管代理方法可以使用“did”或者“will”,我們推薦使用“should”。
集合方法
對于管理著一些對象(每一個對象稱為一個元素)的集合對象,對一些方法如下的約定。
- (void)addElement:(elementType)anObj;- (void)removeElement:(elementType)anObj;- (NSArray *)elements;例子:
- (void)addLayoutManager:(NSLayoutManager *)obj;- (void)removeLayoutManager:(NSLayoutManager *)obj;- (NSArray *)layoutManagers;下面是對這個指南的一些限制條件和改進
- 如果集合是無序的,返回一個NSSet,不要返回一個NSArray
- 若需要將對象插入到集合的某個特定位置,使用類似于如下的方法
需要記憶的一些集合方法的細節(jié)
- 這些方法需要代表與操作對象這件的所屬關系,添加或者插入需要持有該對象,刪除必須釋放該對象。
對于上面的規(guī)范有一些自于NSWindow類的集合方法
- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place; - (void)removeChildWindow:(NSWindow *)childWin; - (NSArray *)childWindows; - (NSWindow *)parentWindow; - (void)setParentWindow:(NSWindow *)window;方法參數(shù)
私有方法
有兩條建議
- 不要使用下劃線開頭,apple在使用。
- 如果子類化一個Cocoa框架類,可以使用公司或者工程名稱作為前綴如“XX_”。如果你的項目為:Byte Flogger,前綴是BF_addObject;
函數(shù)命名
函數(shù)有些需要遵守的規(guī)則
- 函數(shù)命名如方法的命名很相像,但是有一些例外需要注意
- 大部分函數(shù)以描述函數(shù)意義的動詞開頭
查詢屬性的函數(shù)有更多的一些規(guī)則
- 如果函數(shù)返回其第一個參數(shù)的屬性,需要省略動詞。
- 如果通過引用返回其值,使用“get”
- 如果返回一個boolean值,應該以一個變形的動詞開頭
屬性和數(shù)據(jù)類型命名
聲明屬性和實例變量
如果屬性或者實例變量是名字和動詞,格式如下:
@property(__)type nounOrVerb;
舉例
@property (strong) NSString *title; @property (assign) BOOL showsAlpha;如果屬性或者變量是形容詞,但是需要省略“is”前綴,但是需要詳細的約定獲取方法,例如:
@property (assgin,getter=isEditable) Bool editable;許多情況下,當使用一個已經聲明的屬性也應該合成相應的實例變量。
確保實例變量的名字簡潔地描述存儲屬性。通常你不應該直接訪問實例變量。應該通過訪問方法來訪問。為了有助于標志實例變量,可以使用下劃線開頭,例如:
如果使用一個已經聲明的屬性來合成實例變量,在@synthesize語句中詳細說明實例變量。
@implementation MyClass @synthesize showsTitle=_showsTitle;一些注意事項
- 不要顯示的聲明一個公開的實例變量
- 如果需要聲明一個實例變量,明確聲明是@private 或者@protected
- 如果一個實例變量一個可訪問的實例屬性,確保為這個實例變量編寫了訪問器方法
常量
常量根據(jù)創(chuàng)建方式的不同,規(guī)則也不一樣。
枚舉常量
typedef enum _NSMatrixMode {NSRadioModeMatrix = 0,NSHighlightModeMatrix = 1,NSListModeMatrix = 2,NSTrackModeMatrix = 3 } NSMatrixMode;使用const創(chuàng)建常量
使用const的例子
const float NSLightGray;其他類型的常量
- 通常,不要使用#define預處理器命令來創(chuàng)建常量。
- 使用大寫,舉例
- 注意,編譯器定義的宏前后都有兩個下劃線,舉例:
通知和異常
通知和異常的命名也是類似的規(guī)則。但是兩者都有它們推薦的使用方式。
通知
如果一個類有代理,那么代理會通過事先定義好的代理方法來接受大多數(shù)的通知。這些通知名稱應該反映相應的代理方法。例如,全局的NSApplication對象的自動注冊的代理會接受applicationDidBecomeActive:的消息當app發(fā)送一個NSApplicationDidBecomeActiveNotification的通知。
通知使用NSString來表示,使用下面的方式來命名:
[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification例如:
NSApplicationDidBecomeActiveNotificationNSWindowDidMiniaturizeNotificationNSTextViewDidChangeSelectionNotificationNSColorPanelColorDidChangeNotification異常
使用全局的NSString對象來表示異常,命名組成如下:
[Prefix] + [UniquePartOfName] + ExceptionUnique 部分應該將單詞組成在一塊并且大寫每一個單詞的首字母。下面一些例子:
NSColorListIOExceptionNSColorListNotEditableExceptionNSDraggingExceptionNSFontUnavailableExceptionNSIllegalSelectorException可接受的簡寫和縮寫
通常,不應該對接口的名稱進行縮寫。然而,下面列出的縮寫已經被創(chuàng)建或者在過去被使用了很久,因此,可以繼續(xù)使用。關于縮寫有一些其他需要注意的地方:
- 來源于標準C庫的一些縮寫,例如‘alloc’和‘getc’是被允許的。
- 在參數(shù)的命名中可以更加自由的使用縮寫。
| alloc | Allocate |
| alt | Alternate |
| app | Application. For example, NSApp the global application object. However, “application” is spelled out in delegate methods, notifications, and so on. |
| calc | Calculate |
| dealloc | Deallocate. |
| func | Function. |
| horiz | Horizontal. |
| info | Information. |
| init | Initialize (for methods that initialize new objects). |
| int | Integer (in the context of a C int—for an NSInteger value, use integer). |
| max | Maximum. |
| min | Minimum. |
| msg | Message. |
| nib | Interface Builder archive. |
| pboard | Pasteboard (but only in constants). |
| rect | Rectangle. |
| Rep | Representation (used in class name such as NSBitmapImageRep). |
| temp | Temporary. |
| vert | Vertical. |
在計算機產業(yè)中使用的縮寫和首字母縮略詞你可能使用到,下面有些熟知的縮略詞:
ASCII
XML
HTML
URL
RTF
HTTP
TIFF
JPG
PNG
GIF
LZW
ROM
RGB
CMYK
MIDI
FTP
對于框架開發(fā)者的小技巧
這部分是關于框架開發(fā)者的一些建議,略…
總結
- 上一篇: CF894A QAQ
- 下一篇: C++笔试面试题 -- 带答案