iOS 團隊程式設計規範

發表於2017-08-22

前 言

  • 需求是暫時的,只有變化才是永恆的,面向變化程式設計,而不是面向需求程式設計。
  • 不要過分追求技巧,降低程式的可讀性。
  • 簡潔的程式碼可以讓bug無處藏身。要寫出明顯沒有bug的程式碼,而不是沒有明顯bug的程式碼。
  • 先把眼前的問題解決掉,解決好,再考慮將來的擴充套件問題。

一、命名規範

1、統一要求

含義清楚,儘量做到不需要註釋也能瞭解其作用,若做不到,就加註釋,使用全稱,不使用縮寫。

2、類名

大駝峰式命名:每個單詞的首字母都採用大寫字母

==例:== MFHomePageViewController

3、私有變數

  • 私有變數放在 .m 檔案中宣告
  • 以 _ 開頭,第一個單詞首字母小寫,後面的單詞的首字母全部大寫。

==例:== NSString *_somePrivateVariable

4、property變數

  • 小駝峰式命名:第一個單詞以小寫字母開始,後面的單詞的首字母全部大寫
  • 屬性的關鍵字推薦按照 原子性,讀寫,記憶體管理的順序排列。
  • BlockNSString屬性應該使用copy關鍵字
  • 禁止使用synthesize關鍵詞

==例:==

5、巨集和常量命名

  • 對於巨集定義的常量
    • #define 預處理定義的常量全部大寫,單詞間用 _ 分隔
    • 巨集定義中如果包含表示式或變數,表示式或變數必須用小括號括起來。
  • 對於型別常量
    • 對於侷限於某編譯單元(實現檔案)的常量,以字元k開頭,例如kAnimationDuration,且需要以static const修飾
    • 對於定義於類標頭檔案的常量,外部可見,則以定義該常量所在類的類名開頭,例如EOCViewClassAnimationDuration, 仿照蘋果風格,在標頭檔案中進行extern宣告,在實現檔案中定義其值

==例:==

6、Enum

  • Enum型別的命名與類的命名規則一致
  • Enum中列舉內容的命名需要以該Enum型別名稱開頭
  • NS_ENUM定義通用列舉,NS_OPTIONS定義位移列舉

==例:==

7、Delegate

  • delegate做字尾,如
  • optional修飾可以不實現的方法,用required修飾必須實現的方法
  • 當你的委託的方法過多, 可以拆分資料部分和其他邏輯部分, 資料部分用dataSource做字尾. 如
  • 使用didwill通知Delegate已經發生的變化或將要發生的變化。
  • 類的例項必須為回撥方法的引數之一
    1. 回撥方法的引數只有類自己的情況,方法名要符合實際含義
    2. 回撥方法存在兩個以上引數的情況,以類的名字開頭,以表明此方法是屬於哪個類的

==例:==

8、方法

  • 方法名用小駝峰式命名
  • 方法名不要使用new作為字首
  • 不要使用and來連線屬性引數,如果方法描述兩種獨立的行為,使用and來串接它們。
  • 方法實現時,如果引數過長,則令每個引數佔用一行,以冒號對齊。
  • 一般方法不使用字首命名,私有方法可以使用統一的字首來分組和辨識
  • 方法名要與對應的引數名保持高度一致
  • 表示物件行為的方法、執行性的方法應該以動詞開頭
  • 返回性的方法應該以返回的內容開頭,但之前不要加get,除非是間接返回一個或多個值。
  • 可以使用情態動詞(動詞前面can、should、will等)進一步說明屬性意思,但不要使用dodoes,因為這些助動詞沒什麼實際意義。也不要在動詞前使用副詞或形容詞修飾

==例:==

二、程式碼註釋規範

優秀的程式碼大部分是可以自描述的,我們完全可以用程式碼本身來表達它到底在幹什麼,而不需要註釋的輔助。

但並不是說一定不能寫註釋,有以下三種情況比較適合寫註釋:

  • 公共介面(註釋要告訴閱讀程式碼的人,當前類能實現什麼功能)。
  • 涉及到比較深層專業知識的程式碼(註釋要體現出實現原理和思想)。
  • 容易產生歧義的程式碼(但是嚴格來說,容易讓人產生歧義的程式碼是不允許存在的)。

除了上述這三種情況,如果別人只能依靠註釋才能讀懂你的程式碼的時候,就要反思程式碼出現了什麼問題。

最後,對於註釋的內容,相對於“做了什麼”,更應該說明“為什麼這麼做”

1、import註釋

如果有一個以上的import語句,就對這些語句進行分組,每個分組的註釋是可選的。

2、屬性註釋

寫在屬性之後,用兩個空格隔開
==例:==

3、方法宣告註釋:

一個函式(方法)必須有一個字串文件來解釋,除非它:

  • 非公開,私有函式。
  • 很短。
  • 顯而易見。

而其餘的,包括公開介面,重要的方法,分類,以及協議,都應該伴隨文件(註釋):

  • 以/開始
  • 第二行是總結性的語句
  • 第三行永遠是空行
  • 在與第二行開頭對齊的位置寫剩下的註釋。

建議這樣寫:

方法的註釋使用Xcode自帶註釋快捷鍵:Commond+option+/
==例:==

4、程式碼塊註釋

單行的用//+空格開頭,多行的採用/* */註釋

5、TODO

使用//TODO:說明 標記一些未完成的或完成的不盡如人意的地方

==例:==

三、程式碼格式化規範

1、指標*位置

定義一個物件時,指標*靠近變數

==例:== NSString *userName;

2、方法的宣告和定義

在 - 、+和 返回值之間留一個空格,方法名和第一個引數之間不留空格

==例:==

3、程式碼縮排

  • 不要在工程裡使用 Tab 鍵,使用空格來進行縮排。在 Xcode > Preferences > Text Editing 將 Tab 和自動縮排都設定為 4 個空格
  • MethodMethod之間空一行
  • 一元運算子與變數之間沒有空格、二元運算子與變數之間必須有空格

==例:==

4、對method進行分組

使用#pragma mark -method進行分組

5、大括號寫法

  • 對於類的method:左括號另起一行寫(遵循蘋果官方文件)
  • 對於其他使用場景(if,for,while,switch等): 左括號跟在第一行後邊

==例:==

6、property變數

==例:==

四、編碼規範

1、if語句

①、須列出所有分支(窮舉所有的情況),而且每個分支都須給出明確的結果。

==推薦這樣寫:==

==不推薦這樣寫:==

②、不要使用過多的分支,要善於使用return來提前返回錯誤的情況,把最正確的情況放到最後返回。

==推薦這樣寫:==

==不推薦這樣寫:==

③、條件過多,過長的時候應該換行。條件表示式如果很長,則需要將他們提取出來賦給一個BOOL值,或者抽取出一個方法

==推薦這樣寫:==

==不推薦這樣寫:==

④、條件語句的判斷應該是變數在右,常量在左。

==推薦:==

==不推薦:==

if (object == nil)容易誤寫成賦值語句,if (!object)寫法很簡潔

⑤、每個分支的實現程式碼都須被大括號包圍

==推薦:==

==不推薦:==

可以如下這樣寫:

2、for語句

①、不可在for迴圈內修改迴圈變數,防止for迴圈失去控制。

②、避免使用continue和break。

continuebreak所描述的是“什麼時候不做什麼”,所以為了讀懂二者所在的程式碼,我們需要在頭腦裡將他們取反。

其實最好不要讓這兩個東西出現,因為我們的程式碼只要體現出“什麼時候做什麼”就好了,而且通過適當的方法,是可以將這兩個東西消滅掉的:

  • 如果出現了continue,只需要把continue的條件取反即可

我們可以看到,通過判斷字串裡是否含有“bad”這個prefix來過濾掉一些值。其實我們是可以通過取反,來避免使用continue的:

  • 消除while裡的break:break的條件取反,併合併到主迴圈裡

while裡的break其實就相當於“不存在”,既然是不存在的東西就完全可以在最開始的條件語句中將其排除。

while裡的break:

取反併合併到主條件:

  • 在有返回值的方法裡消除break:break轉換為return立即返回

有人喜歡這樣做:在有返回值的方法裡break之後,再返回某個值。其實完全可以在break的那一行直接返回。

遇到錯誤條件直接返回:

這樣寫的話不用特意宣告一個變數來特意儲存需要返回的值,看起來非常簡潔,可讀性高。

3、Switch語句

①、每個分支都必須用大括號括起來

推薦這樣寫:

②、使用列舉型別時,不能有default分支, 除了使用列舉型別以外,都必須有default分支

Switch語句使用列舉型別的時候,如果使用了default分支,在將來就無法通過編譯器來檢查新增的列舉型別了。

4、函式

①、一個函式只做一件事(單一原則)

每個函式的職責都應該劃分的很明確(就像類一樣)。

==推薦:==

==不推薦:==

②、對於有返回值的函式(方法),每一個分支都必須有返回值

==推薦:==

==不推薦:==

③、對輸入引數的正確性和有效性進行檢查,引數錯誤立即返回

==推薦:==

④、如果在不同的函式內部有相同的功能,應該把相同的功能抽取出來單獨作為另一個函式

原來的呼叫:

將a,b函式抽取出來作為單獨的函式

⑤、將函式內部比較複雜的邏輯提取出來作為單獨的函式

一個函式內的不清晰(邏輯判斷比較多,行數較多)的那片程式碼,往往可以被提取出去,構成一個新的函式,然後在原來的地方呼叫它這樣你就可以使用有意義的函式名來代替註釋,增加程式的可讀性。

舉一個傳送郵件的例子:

中間的部分稍微長一些,我們可以將它們提取出來:

然後再看一下原來的程式碼:


參考資料:
iOS 程式碼規範
iOS開發總結之程式碼規範
iOS開發程式碼規範(通用)
Objective-C開發編碼規範
【iOS】命名規範
Ios Code Specification
Apple Coding Guidelines for Cocoa
Google Objective-C Style Guide

相關文章