【iOS翻譯】 Cocoa編碼規範

原文地址:

http://www.cnblogs.com/yangfaxian/p/4673894.html?sukey=b0cb5c5b9e501303cdfc92afc2415f8b2d1a3cbac6baecd52b8a67d68fa3f2695abd8f230b34ae248ad0c22a9de653ad


簡介:

本文整理自Apple文檔《Coding Guidelines for Cocoa》。這份文檔原意是給Cocoa框架、插件及公共API開發者提供一些編碼指導,實質上相當於Apple內部的編碼規範。在多人協作時,一份統一的代碼規範大大減少開發者之間的溝通成本,極力推薦。 
 
目錄:
一、代碼命名基礎
二、方法
三、函數
四、Property及其他
五、縮寫  
 
 
 
一、代碼命名基礎
1.通用原則


1.1 清晰


儘量清晰又簡潔,無法兩全時清晰更重要
Code


Commentary


insertObject:atIndex:





insert:at:


不清晰,insert什麼?at表示什麼?


removeObjectAtIndex:





removeObject:


√ ,因爲參數指明瞭移除對象


remove:


不清晰,要移除什麼?


 


通常不應縮寫名稱,即使方法名很長也應完整拼寫
    ◦    你可能認爲某個縮寫衆所周知,但其實未必,特別是你周圍的開發者語言文化背景不同時


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


Code


Commentary


destinationSelection





destSel


不清晰


setBackgroundColor:





setBkgdColor:


不清晰


 


API命名避免歧義,例如一個方法名有多種理解
Code


Commentary


sendPort


發送還是返回一個port ?


displayName


顯示一個名字還是返回UI界面上的標題?


 


1.2 一致


盡力保持Cocoa編程接口命名一致
    ◦    如果有疑惑,請瀏覽當前頭文件或者參考文檔


 


當某個類的方法使用了多態時,一致性尤其重要
    ◦    不同類裏,功能相同的方法命名也應相同


Code


Commentary


- (NSInteger)tag


定義在 NSView, NSCell, NSControl.


- (void)setStringValue:(NSString *)


定義在許多Cocoa類裏


 


1.3 避免自引用(self Reference)


命名不應自引用
    ◦   這裏的自引用指的是在詞尾引用自身


Code


Commentary


NSString





NSStringObject


自引用,所有NSString都是對象,不用額外聲明


 


Mask與Notification忽略此規則
Code


Commentary


NSUnderlineByWordMask





NSTableViewColumnDidMoveNotification





 


2.前綴


       前綴是編程接口命名的重要部分,它們區分了軟件的不同功能區域:


前綴可以防止第三方開發者與Apple的命名衝突
    ◦    同樣可以防止Apple內部的命名衝突


 


前綴有指定格式
    ◦    它由二到三個大寫字母組成,不使用下劃線和子前綴


 


命名類、協議、函數、常量和typedef結構體時使用前綴
    ◦    方法名不使用前綴(因爲它存在於特定類的命名空間中)


    ◦    結構體字段不使用前綴 


Prefix


Cocoa Framework


NS


Foundation


NS


Application Kit


AB


Address Book


IB


Interface Builder


 


3.書寫約定


  在命名API元素時, 使用駝峯命名法(如runTheWordsTogether),並注意以下書寫約定:


方法名
    ◦    小寫第一個字母,大寫之後所有單詞的首字母,不使用前綴


    ◦    如果方法名以一個衆所周知的大寫縮略詞開始,該規則不適用


      ▪    如TIFFRepresentation (NSImage)


fileExistsAtPath:isDirectory:
 


 函數及常量名
    ◦    使用與其關聯類相同的前綴,並大寫首字母


NSRunAlertPanel
NSCellDisabled 
 


 標點符號
    ◦    由多個單詞組成的名稱,別使用標點符號作爲名稱的一部分


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


 


避免使用下劃線作爲私有方法的前綴,Apple保留這一方式的使用
    ◦    強行使用可能會導致命名衝突,即Apple已有的方法被覆蓋,這會導致災難性後果


    ◦    實例變量使用下劃線作爲前綴還是允許的


 


4.class與protocol命名


class
    ◦    class的名稱應該包含一個名詞,用以表明這個類是什麼(或者做了什麼),並擁有合適的前綴


      ▪    如NSString、NSDate、NSScanner、UIApplication、UIButton


 


不關聯class的protocol
    ◦    大多數protocol聚集了一堆相關方法,並不關聯class


    ◦    這種protocol使用ing形式以和class區分開來


Code


Commentary


NSLocking





NSLock


不好,看起來像是一個class


 


關聯class的protocol
    ◦    一些protoco聚集了一堆無關方法,並試圖與某個class關聯在一起,由這個class來主導


    ◦    這種protocol與class同名


      ▪    如NSObject protocol


 


5.頭文件


  頭文件的命名極其重要,因爲它可以指出頭文件包含的內容:


聲明一個孤立的class或protocol
    ◦    將聲明放入單獨的文件


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


Header file


Declares


NSLocale.h


包含NSLocale class.


  


聲明關聯的class或protocol
    ◦    將關聯的聲明(class/category/protocol)放入同一個頭文件


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


Header file


Declares


NSString.h


包含NSString和NSMutableString classes.


NSLock.h


包含NSLocking protocol 和 NSLock, NSConditionLock, NSRecursiveLock classes.


  


Framework頭文件
    ◦    每個framework都應該有一個同名頭文件


    ◦    Include了框架內其他所有頭文件


Header file


Framework


Foundation.h


Foundation.framework.


 


添加API到另一個framework
    ◦    如果要在一個framework中爲另一個framework的class catetgory添加方法,加上單詞“Additions” 


      ▪    如Application Kit的NSBundleAdditions.h 文件


 


關聯的函數、數據類型
    ◦    如果你有一組關聯的函數、常量、結構體或其他數據類型,將它們放到一個名字合適的頭文件中


      ▪    如Application Kit的NSGraphics.h 




 


二、方法


1.通用原則 


以小寫字母開始,之後單詞的首字母大寫
    ◦    以衆所周知的縮寫開始可以大寫,如TIFF、PDF


    ◦    私有方法可以加前綴


                         


如果方法代表對象接收的動作,以動詞開始
    ◦    不要使用 do 或 does 作爲名字的一部分,因爲助動詞在這裏很少有實際意義


    ◦    同樣的,也別在動詞之前使用副詞和形容詞


- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem  


如果方法返回接收者的屬性,以 接收者 + 接收的屬性 命名
    ◦   除非間接返回多個值,否則不要使用 get 單詞(爲了與accessor methods區分) 


- (NSSize)cellSize;





- (NSSize)calcCellSize;





- (NSSize)getCellSize;





 


在所有參數之前使用關鍵字 
- (void)sendAction:(SEL)aSelector


              toObject:(id)anObject


            forAllCells:(BOOL)flag;





- (void)sendAction:(SEL)aSelector


                          :(id)anObject


                          :(BOOL)flag;





 


確保參數之前的關鍵字充分描述了參數
- (id)viewWithTag:(NSInteger)aTag;





- (id)taggedView:(int)aTag;





 


 


創建自定義 init 方法時,記得指明關聯的元素
- (id)initWithFrame:(CGRect)frameRect;





- (id)initWithFrame:(NSRect)frameRect


                   mode:(int)aMode


               cellClass:(Class)factoryId


      numberOfRows:(int)rowsHigh


 numberOfColumns:(int)colsWide;





 


不要使用 and 來連接作爲接收者屬性的關鍵字
    ◦  雖然下面的例子使用 and 看似不錯,但是一旦參數非常多時就容易出現問題


- (int)runModalForDirectory:(NSString *)path


                                   file:(NSString *)name


                               types:(NSArray *)fileTypes;





- (int)runModalForDirectory:(NSString *)path


                      andFile:(NSString *)name


                     andTypes:(NSArray *)fileTypes;





   


除非方法描述了兩個獨立的操作,才使用 and 來連接它們
- (BOOL)openFile:(NSString *)fullPath


   withApplication:(NSString *)appName


    andDeactivate:(BOOL)flag;





  


2.getter和setter方法(Accessor Methods)


如果property表示爲名詞,格式如下
    ◦    - (type)noun;


    ◦    - (void)setNoun:(type)aNoun;  


    ◦    - (BOOL)isAdjective;


- (NSString *)title;
- (void)setTitle:(NSString *)aTitle; 
 


如果property表示爲形容詞,格式如下
    ◦    - (BOOL)isAdjective;


    ◦    - (void)setAdjective:(BOOL)flag;  


- (BOOL)isEditable; 
- (void)setEditable:(BOOL)flag; 
 


如果property表示爲動詞,格式如下(動詞用一般現在時)
    ◦    - (BOOL)verbObject;


    ◦    - (void)setVerbObject:(BOOL)flag;  


- (BOOL)showsAlpha;
- (void)setShowsAlpha:(BOOL)flag; 
 


不要把動詞的過去分詞形式當作形容詞使用  
- (void)setAcceptsGlyphInfo:(BOOL)flag;





- (BOOL)acceptsGlyphInfo;





- (void)setGlyphInfoAccepted:(BOOL)flag;





- (BOOL)glyphInfoAccepted;





 


你可能使用情態動詞(can、should、will等)來增加可讀性,不過不要使用 do或 does
- (void)setCanHide:(BOOL)flag;





- (BOOL)canHide;





- (void)setShouldCloseDocument:(BOOL)flag;





- (BOOL)shouldCloseDocument;





- (void)setDoesAcceptGlyphInfo:(BOOL)flag;





- (BOOL)doesAcceptGlyphInfo;





 


只有方法需要間接返回多個值的情況下才使用 get
    ◦    像這種接收多個參數的方法應該能夠傳入nil,因爲調用者未必對每個參數都感興趣


- (void)getLineDash:(float *)pattern


                    count:(int *)count


                   phase:(float *)phase;


NSBezierPath.


  


3.Delegate方法


以發送消息的對象開始
    ◦   省略了前綴的類名和首字母小寫


- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row; 
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename; 
 


以發送消息的對象開始的規則不適用下列兩種情況
    ◦   只有一個sender參數的方法


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


    ◦   響應notification的方法(方法的唯一參數就是notification)


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


使用單詞 did 和 will 來通知delegate
    ◦     did 表示某些事已發生


    ◦     will 表示某些事將要發生


- (void)browserDidScroll:(NSBrowser *)sender;
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window; 
  


詢問delegate是否可以執行某個行爲時可以使用 did 或 will,不過 should 更完美  
- (BOOL)windowShouldClose:(id)sender;
  


 


4.集合方法   


爲了管理集合中的元素,集合應該有這幾個方法
    ◦    - (void)addElement:(elementType)anObj;


    ◦    - (void)removeElement:(elementType)anObj;


    ◦    - (NSArray *)elements;


- (void)addLayoutManager:(NSLayoutManager *)obj;
- (void)removeLayoutManager:(NSLayoutManager *)obj;
- (NSArray *)layoutManagers;  
 


如果集合是無序的,返回一個NSSet比NSarray更好
如果需要在集合中的特定位置插入元素,使用類似下面的方法
- (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index; 
- (void)removeLayoutManagerAtIndex:(int)index; 
 


其他集合方法示例
- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
- (void)removeChildWindow:(NSWindow *)childWin;
- (NSArray *)childWindows;
- (NSWindow *)parentWindow;
- (void)setParentWindow:(NSWindow *)window; 
 


 


5.方法參數 


參數名以小寫字母開始,之後的單詞首字母大寫
如:removeObject:(id)anObject
  


別使用 ”pointer” 或 ”ptr” 命名
    ◦    參數類型裏就已表明它是否是一個指針


 


避免只有一到二個字母的參數名
 


避免只有幾個字母的縮寫
複製代碼
...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保留這一使用方式
    ◦    因爲若是你的私有方法名已被Apple使用,覆蓋它將會產生極難追蹤的BUG


 


如果繼承自大型Cocoa框架(如UIView),請確保子類的私有方法名與父類不一樣
    ◦    可以爲私有方法加一個前綴,如公司名或項目名:XX_


      ▪    例如你的項目叫做Byte Flogger,那麼前綴可能是:BF_addObject


    ◦    總之,爲子類的私有方法添加前綴是爲了不覆蓋其父類的私有方法




 


三、函數


函數的命名類似方法,但有兩點要注意
    ◦    你使用的類和常量擁有相同的前綴


    ◦    前綴後的首字母大寫


 


許多函數名以描述其作用的動詞開始
NSHighlightRect
NSDeallocateObject 
 


查詢屬性的函數有進一步的命名規則
    ◦    如果函數返回首個參數的屬性,省略動詞


unsigned int NSEventMaskFromType(NSEventType type) 
float NSHeight(NSRect aRect) 
 


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


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


    ◦    如果返回的是boolean值,應該靈活使用動詞 


BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)
 


 


四、Property及其他


1.Property與實例變量


1.1 Property


Property命名規則與第二章accessor methods一樣(因爲兩者緊密聯繫)
 


如果property表示爲一個名詞或動詞,格式如下
    ◦    @property (…) 類型 名詞/動詞 ;


@property (strong) NSString *title;
@property (assign) BOOL showsAlpha; 
 


如果property表示爲一個形容詞
    ◦    可省略 ”is” 前綴


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


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


1.2 實例變量


通常不應該直接訪問實例變量
    ◦    init、dealloc、accessor methods等方法內部例外


 


實例變量以下劃線 “_” 開始
    ◦    確保實例變量描述了所存儲的屬性


@implementation MyClass {
   BOOL _showsTitle;

 


如果想要修改property的實例變量名,使用 @synthesize語句
@implementation MyClass
@synthesize showsTitle=_showsTitle;
 


爲一個class添加實例變量時,有幾點需要注意:


避免聲明公有實例變量
    ◦    開發者關注的應該是對象接口,而不是其數據細節


    ◦    你可以通過使用property來避免聲明實例變量


 


如果需要聲明實例變量,指定關鍵字@private 或 @protected
    ◦    如果你希望子類可以直接訪問某個實例變量,使用 @protected 關鍵字


 


如果一個實例變量是某個類可訪問的屬性,確保寫了accessor methods
    ◦    如果有可能,還是使用property


 


2.常量  


2.1 枚舉常量


使用枚舉來關聯一組integer常量  
枚舉常量和typedef遵循函數的命名規範,下面的例子是 NSMatrix.h
typedef enum _NSMatrixMode {
    NSRadioModeMatrix            = 0,
    NSHighlightModeMatrix       = 1,           
    NSListModeMatrix            = 2, 
    NSTrackModeMatrix           = 3
} NSMatrixMode; 
 


你可以爲bit masks之類的東西創建一個匿名枚舉 
複製代碼
enum { 
    NSBorderlessWindowMask       = 0, 
    NSTitledWindowMask           = 1 << 0,
    NSClosableWindowMask         = 1 << 1,
    NSMiniaturizableWindowMask   = 1 << 2, 
    NSResizableWindowMask         = 1 << 3
};   
複製代碼
 


2.2 使用const關鍵字的常量 


使用const關鍵字來創建一個float常量
    ◦    你可以使用const關鍵字來創建一個與其他常量不相關的integer常量,否則,使用枚舉


    ◦    使用const關鍵字的常量也遵循函數的命名規則 


const float NSLightGray;
 


2.3 其他常量類型  


通常不應使用 #define 預編譯指令來創建常量
    ◦    integer常量,使用枚舉


    ◦    float常量,使用 const 修飾符


 


 對 #define 預編譯指令,大寫所有字母
    ◦    比如 DEBUG 判斷


#ifdef DEBUG 
 


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


定義NSString常量來作爲Notification和Key值
    ◦   這樣做可以有效防止拼寫錯誤


APPKIT_EXTERN NSString *NSPrintCopies;
 


3.Notifications與Exceptions


3.1 Notifications  


Notification的格式
[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification
NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification 
NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification
 


3.2 Exceptions  


Exception的格式
[Prefix] + [UniquePartOfName] + Exception
NSColorListIOException
NSColorListNotEditableException
NSDraggingException  
NSFontUnavailableException
NSIllegalSelectorException
  


 


五、縮寫


設計編程接口時通常不應使用縮寫,但下列已被廣泛使用的縮寫名稱除外
    ◦    標準C庫中的縮寫名,如:alloc、init


    ◦    參數名可自由使用縮寫,如:imageRep、col、obj、otherWin


縮寫    全稱


alloc Allocate.


alt   Alternate.


app  Application.


calc  Calculate.


dealloc  Deallocate.


func     Function.


horiz   Horizontal.


info    Information.


init    Initialize.


int     Integer


max   Maximum.


min   Minimum.


msg   Message.


nib     Interface Builder archive.


pboard  Pasteboard.


rect     Rectangle.


Rep     Representation.


temp   Temporary.


vert    Vertical.


   


縮寫   全稱


ASCII   American Standard Code for Information Interchange


PDF      Portable Document Format


XML      Extensible Markup Language


HTML    HyperText Markup Language


URL     Uniform Resource Locator


RTF      Rich Text Format


HTTP     HyperText Transfer Protocol


TIFF       Tagged Image File Format


JPG/JPEG    Joint Photographic Experts GROUP


PNG        Portable Network Graphic Format


GIF        Graphics Interchange Format


LZW   Lempel Ziv Welch


ROM   Read-Only Memory


RGB   R(red)、G(green)、B(blue)


CMYK   C:Cyan、M:Magenta、Y:Yellow、K:Key Plate(blacK)


MIDI     Musical Instrument Digital Interface


FTP      File Transfer Protocol


 


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章