【iOS 搭建基礎框架】編碼規範 (命名規範篇)

Bit俠發表於2018-01-24

本篇是 iOS 搭建基礎框架 系列,第一部分 編碼規範 的第一篇 命名規範篇

其他相關文章傳送門如下:


本篇內容,摘取自蘋果、谷歌的文件翻譯,還有網上大神們貢獻的資料。

主要是為了讓自己保持程式碼的一致性 and 傳說中的優雅 ? ,也為以後的團隊總結出一份基礎的通用編碼規範。(確實想的有點遠 ?)

希望能讓你有所收穫,沒有收穫也沒關係,記得點贊~ ?

命名規範

類名 (Class)

  1. 避免潛在的命名衝突,設定 Class Prefix

    設定 Class Prefix

    設定整個專案的統一類名字首。 由於蘋果公司保留使用"兩個字母字首"的所有權,所以專案裡的字首應取三個字母為宜。

  2. 類名的命名採用 大駝峰命名法 即每個單詞的首字母大寫。


類別 (Category)

如下:類別名新增 大寫字首 KL , 方法名新增 小寫字首 kl

NSObject+KLNetworkingMethods.h

@interface NSObject (KLNetworkingMethods)

- (BOOL)kl_isEmptyObject;

@end
複製程式碼

委託 (Delegate)

  • 第一個引數是觸發委託的物件
  • 第一個關鍵詞是觸發物件的類名
  • 除非該方法只有一個引數
// 第一個關鍵詞為觸發委託的類名
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;  

// 當只有一個"sender"引數時可以省略類名
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
複製程式碼

根據委託方法觸發的時機和目的,使用should,will,did等關鍵詞

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

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;、

- (BOOL)windowShouldClose:(id)sender;
複製程式碼

通知 (Notification)

通知常用於在模組間傳遞訊息,所以通知要儘可能地表示出發生的事件,通知的命名正規化是:

[觸發通知的類名] + [Did | Will] + [動作] + Notification
複製程式碼

栗子?

NSApplicationDidBecomeActiveNotification
UIKeyboardWillShowNotification
NSUserDefaultsDidChangeNotification
UITextFieldTextDidBeginEditingNotification
複製程式碼

常量或者巨集

  • 常量:k為字首,後續遵循 駝峰命名法kConstantName

  • 巨集:全部使用大寫字母加下劃線的形式,MACORS_NAME


方法(Methods)

命名採用 小駝峰命名法 即首個單詞全部用小寫字母,後續的單詞首字母大寫。

方法名中不應該有標點符號(包括下劃線),除了以下的情況:

  • 可以用帶下劃線的小寫字首來命名私有方法或者類別中的方法
- (void)kl_setControls
複製程式碼

如果方法表示讓物件執行一個動作,使用動詞打頭來命名,注意不要使用dodoes這種多餘的關鍵字,動詞本身的暗示就足夠了:

//正確,使用屬性名來命名方法
- (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;
複製程式碼

不要用and來連線兩個引數,通常and用來表示方法執行了兩個相對獨立的操作(從設計上來說,這時候應該拆分成兩個獨立的方法):

//錯誤,不要使用"and"來連線引數
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;

//正確,使用"and"來表示兩個相對獨立的操作
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
複製程式碼

方法的引數命名也有一些需要注意的地方:

  • 和方法名類似,引數的第一個字母小寫,後面的每一個單詞首字母大寫
  • 不要再方法名中使用類似pointer,ptr這樣的字眼去表示指標,引數本身的型別足以說明
  • 不要使用只有一兩個字母的引數名
  • 不要使用簡寫,拼出完整的單詞

存取方法(Accessor Methods)

存取方法是指用來獲取和設定類屬性值的方法,屬性的不同型別,對應著不同的存取方法規範:

//屬性是一個名詞時的存取方法正規化
- (type)noun;
- (void)setNoun:(type)aNoun;
//栗子
- (NSString *)title;
- (void)setTitle:(NSString *)aTitle;

//屬性是一個形容詞時存取方法的正規化
- (BOOL)isAdjective;
- (void)setAdjective:(BOOL)flag;
//栗子
- (BOOL)isEditable;
- (void)setEditable:(BOOL)flag;

//屬性是一個動詞時存取方法的正規化
- (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;

//錯誤,不要使用"do"或者"does"
- (void)setDoesAcceptGlyphInfo:(BOOL)flag;
- (BOOL)doesAcceptGlyphInfo;
複製程式碼

為什麼 Objective-C 中不適用get字首來表示屬性獲取方法?因為getObjective-C 中通常只用來表示從函式指標返回值的函式:

//三個引數都是作為函式的返回值來使用的,這樣的函式名可以使用"get"字首
- (void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;
複製程式碼

集合操作類方法(Collection Methods)

有些物件管理著一系列其它物件或者元素的集合,需要使用類似“增刪查改”的方法來對集合進行操作,這些方法的命名正規化一般為:

//集合操作正規化
- (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;
複製程式碼

如果管理的集合元素中有指向管理物件的指標,要設定成weak型別以防止引用迴圈。

下面是SDK中NSWindow類的集合操作方法:

- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
- (void)removeChildWindow:(NSWindow *)childWin;
- (NSArray *)childWindows;
- (NSWindow *)parentWindow;
- (void)setParentWindow:(NSWindow *)window;
複製程式碼

命名屬性和例項變數(Properties&Instance Variables)

屬性和物件的存取方法相關聯,屬性的第一個字母小寫,後續單詞首字母大寫,不必新增字首。屬性按功能命名成名詞或者動詞:

//名詞屬性
@property (strong) NSString *title;

//動詞屬性
@property (assign) BOOL showsAlpha;
複製程式碼

屬性也可以命名成形容詞,這時候通常會指定一個帶有is字首的get方法來提高可讀性:

@property (assign, getter=isEditable) BOOL editable;
複製程式碼

命名例項變數,在變數名前加上_字首(有些有歷史的程式碼會將_放在後面),其它和命名屬性一樣:

@implementation MyClass {
    BOOL _showsTitle;
}
複製程式碼

一般來說,類需要對使用者隱藏資料儲存的細節,所以不要將例項方法定義成公共可訪問的介面,可以使用@private@protected字首。

按蘋果的說法,不建議在除了initdealloc方法以外的地方直接訪問例項變數,但很多人認為直接訪問會讓程式碼更加清晰可讀,只在需要計算或者執行操作的時候才使用存取方法訪問,我就是這種習慣,所以這裡不作要求。

###命名常量(Constants)

如果要定義一組相關的常量,儘量使用列舉型別(enumerations),列舉型別的命名規則和函式的命名規則相同。 建議使用 NS_ENUMNS_OPTIONS 巨集來定義列舉型別,參見官方的 Adopting Modern Objective-C 一文:

//定義一個列舉
typedef NS_ENUM(NSInteger, NSMatrixMode) {
    NSRadioModeMatrix,
    NSHighlightModeMatrix,
    NSListModeMatrix,
    NSTrackModeMatrix
};
複製程式碼

定義bit map:

typedef NS_OPTIONS(NSUInteger, NSWindowMask) {
    NSBorderlessWindowMask      = 0,
    NSTitledWindowMask          = 1 << 0,
    NSClosableWindowMask        = 1 << 1,
    NSMiniaturizableWindowMask  = 1 << 2,
    NSResizableWindowMask       = 1 << 3
};
複製程式碼

使用const定義浮點型或者單個的整數型常量,如果要定義一組相關的整數常量,應該優先使用列舉。常量的命名規範和函式相同:

const float NSLightGray;
複製程式碼

不要使用#define巨集來定義常量,如果是整型常量,儘量使用列舉,浮點型常量,使用const定義。#define通常用來給編譯器決定是否編譯某塊程式碼,比如常用的:

#ifdef DEBUG
複製程式碼

注意到一般由編譯器定義的巨集會在前後都有一個__,比如*__MACH__*。


註釋

檔案註釋

每一個檔案都 必須 寫檔案註釋,檔案註釋最基本的應包含

  • 檔名稱
  • 作者資訊(姓名、郵箱、Github等)
  • 檔案的描述,及其作用
  • 版本資訊

最基礎的檔案註釋栗子?

/*******************************************************************************

    File name:     AppDelegate.h
    Author:        Ferryman (Li KaiLong)
 
    Description:
 
    History:

 
 ********************************************************************************/
複製程式碼

Xcode 裡,建立的新檔案都有預設的檔案註釋,可通過 Xcode 9自定義文字巨集 新特性統一新增我們的檔案註釋模組,保持整個工程統一的檔案註釋風格。 重要!很重要!! 非常重要!!!

統一檔案註釋模組新增的技巧可參考我這篇【iOS 小技巧】Xcode自定義檔案頭部註釋

程式碼註釋

“自解釋”(self-documenting)的程式碼是我們應該做到的,但仍然需要詳細的註釋來說明引數的意義、返回值、功能以及可能的副作用。

方法、類、協議、類別的定義都需要註釋,推薦採用Apple的標準註釋風格,好處是可以在引用的地方option + 滑鼠左鍵自動彈出註釋,非常方便。

生成註釋格式的方法採用 Xcode 自帶的註釋快捷鍵功能

  • 單行註釋:在需要註釋的地方按 command + /
  • 標註: 在屬性或者方法名的上面(空白) 的地方按 command + option + /

AnnotationTemplateGif

特別注意:

  • 協議、委託的註釋要明確說明其被觸發的條件

  • 如果在註釋中要引用引數名或者方法函式名,使用||將引數或者方法括起來以避免歧義:

定義在標頭檔案裡的介面方法、屬性必須要有註釋!

哥們,都浪到這了,順手點個贊❤️唄~

參考文件

相關文章