本篇是 iOS 搭建基礎框架 系列,第一部分 編碼規範 的第一篇 命名規範篇。
其他相關文章傳送門如下:
本篇內容,摘取自蘋果、谷歌的文件翻譯,還有網上大神們貢獻的資料。
主要是為了讓自己保持程式碼的一致性 and 傳說中的優雅 ? ,也為以後的團隊總結出一份基礎的通用編碼規範。(確實想的有點遠 ?)
希望能讓你有所收穫,沒有收穫也沒關係,記得點贊~ ?
命名規範
類名 (Class)
-
避免潛在的命名衝突,設定 Class Prefix
設定整個專案的統一類名字首。 由於蘋果公司保留使用"兩個字母字首"的所有權,所以專案裡的字首應取三個字母為宜。
-
類名的命名採用 大駝峰命名法 即每個單詞的首字母大寫。
類別 (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
複製程式碼
如果方法表示讓物件執行一個動作,使用動詞打頭來命名,注意不要使用do
,does
這種多餘的關鍵字,動詞本身的暗示就足夠了:
//正確,使用屬性名來命名方法
- (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
字首來表示屬性獲取方法?因為get
在 Objective-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
字首。
按蘋果的說法,不建議在除了init
和dealloc
方法以外的地方直接訪問例項變數,但很多人認為直接訪問會讓程式碼更加清晰可讀,只在需要計算或者執行操作的時候才使用存取方法訪問,我就是這種習慣,所以這裡不作要求。
###命名常量(Constants)
如果要定義一組相關的常量,儘量使用列舉型別(enumerations),列舉型別的命名規則和函式的命名規則相同。
建議使用 NS_ENUM
和 NS_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 + /
特別注意:
-
協議、委託的註釋要明確說明其被觸發的條件
-
如果在註釋中要引用引數名或者方法函式名,使用
||
將引數或者方法括起來以避免歧義:
定義在標頭檔案裡的介面方法、屬性必須要有註釋!
哥們,都浪到這了,順手點個贊❤️唄~