標籤:return while att java boa ams fit dcl 代碼規範
1.1類名
類名(以及類別、協議名)應首字母大寫,並以駝峰格式分割單詞。
1.類的首碼
1)所有類名、枚舉、結構、protocol定義時最好加一個統一的標示符,可以是項目縮寫,或者個人項目的名稱縮寫,例如都加上全大寫的XM作為首碼
2)根據功能模組可以在給功能模組的類添加功能模組的名稱首碼,如使用者中心的profileViewController.可以命名XMProfileViewController.
1.2類的尾碼
所有protocol定義時,都加上尾碼Delegate 。如,XMRefreshViewDelegate,表示RefreshView的協議;
所有的控制器都加上Controller,所有的通知名都加上Notification。
類別命名
類名+標識+擴充(UIImageView +HP+Web)
//正例:XMBankCardModel/ XMBindCardModel/ XMUUIDModel/ //反例:xmBankCardModel / XMbindCardModel / XMUuidModel/
1.2測試類別名
【強制】測試類別命名以它要測試的類的名稱開始,以Test結尾
//正例:XMRequestsTest
1.3數組定義
【強制】*是數群組類型的一部分,數組定義如下:
//正例:NSArray *dataSouceArr;
1.4方法名、參數名、成員變數、局部變數
【強制】參數名、局部變數都統一使用lowerCamelCase。盡量是英文文法表達,避免使用漢語拼音來命名,嚴禁使用拼音與英文混合的命名方式。
//正例:endKeyboardRect / certNoView //反例: EndKeyboardRect / shenFenZhengView
1.5成員變數
【強制】成員變數必須以底線開頭,統一使用lowerCamelCase。盡量是英文文法表達,避免使用漢語拼音來命名,嚴禁使用拼音與英文混合的命名方式。
//正例:_selectedMonthIndex/ _isShowResult//反例:selectedMonthIndex/ isShowJieGuo
1.6方法名
【強制】應該在方法類型(-/+ 符號)之後有一個空格。在方法各個段之間應該也有一個空格。在參數之前應該包含一個具有描述性的關鍵字來描述參數,方法名統一使用lowerCamelCase。
//正例: - (void)keyboardWasShown:(NSNotification*)notification;//反例: -(void)keyboardWasShown:(NSNotification*)notification; //[方法類型之後未空格]
1.7常量命名
【推薦】常量指的是宏(#define)、枚舉(enum)、常量(const)等,使用小寫”k“作為首碼,名稱遵循大駝峰命名法
//正例:static NSTimeInterval kAIFNetworkingTimeoutSeconds = 20.0f;//反例: static NSString * const codeSuccess = @"0000"
1.8 Bundle Identifier命名
【強制】採用反網域名稱命名規則,全部使用小寫字母。一級包名為com,二級包名根據應用進行命名。
//正例:com.elong.xman
1.9設計模式命名
【推薦】如果使用到了設計模式,建議在類名中體現出具體模式。
說明:將設計模式體現在名字中,有利於閱讀者快速理解架構設計思想。
//正例:@interface AIFApiProxy : NSObject@interface AIFServiceFactory : NSObject
1.10枚舉類命名
【推薦】枚舉類名和枚舉成員以XM開頭並使用UpperCamelCase,推薦使用新的固定基本類型規格,因為它有更強的類型檢查和代碼補全
說明:枚舉其實就是特殊的常量類,且構造方法被預設強制是私人。
//正例:typedef NS_ENUM(NSUInteger, XMRequestMethod) { XMRequestMethodGET = 0, XMRequestMethodPOST, XMRequestMethodPUT, XMRequestMethodDELETE, XMRequestMethodHEAD,};
2. 常量,字面量,枚舉定義
2.1常量是容易重複被使用和無需通過尋找和代替就能快速修改值。常量應該使用static來聲明而不是使用#define,除非顯式地使用宏。
//正例:static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com"; //反例:#define CompanyName @"RayWenderlich.com"
2.2 NSString、NSDictionary、NSArray和NSNumber的字面值應該在建立這些類的不可變執行個體時被使用。請特別注意nil值不能傳入NSArray和NSDictionary字面值,因為這樣會導致crash。
//正例:NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"]; NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"}; //反例:NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
2.3當使用enum時,推薦使用新的固定基本類型規格,因為它有更強的類型檢查和代碼補全。現在SDK有一個宏NS_ENUM()來協助和鼓勵你使用固定的基本類型。
//正例:typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) { RWTLeftMenuTopItemMain, RWTLeftMenuTopItemShows, RWTLeftMenuTopItemSchedule }; //反例:enum GlobalConstants { kMaxPinSize = 5, kMaxPinCount = 500, };
3. OOP規約
3.1盡量使用不可變對象
【強制】在設計類的時候,應該充分應用屬性來封裝資料。具體到實踐中,應該盡量把對外公布的屬性設為唯讀(read-only),而且只在卻有必要時才將屬性對外公布。
3.2 通過委託和資料來源協議進行對象之間的通訊
【強制】對象之間通訊方式有很多種,委託模式是OC中最常用的一種模式,能夠將資料和商務邏輯解耦。
3.3將類的實現代碼分散到便於管理的數個分類中
【強制】類中經常填滿各種方法,而這些方法的代碼全部堆到一個巨大的實現檔案中,效果不好。可以使用OC的“分類”機制,把類代碼按邏輯劃入幾個分區中,這樣開發和調試都有好處。
3.4 在delloc方法中只釋放引用並解除監聽
【強制】主要釋放對象所持有的引用,另外把原來配置過的觀測行為都清理掉。
3.5 用弱引用避免保留環
【強制】保留環會導致記憶體流失,推薦用非擁有關係(弱引用)來解決,在ARC中,將屬性聲明為weak或者assign.
3.6 以自動釋放池快降低記憶體峰值
【強制】@autoreleasepool這種方式建立,對象收到autorelease訊息後,系統將其 放入最頂端的池裡,可以有效降低記憶體的峰值。
3.7 使用dispatch_once來執行只需運行一次的安全執行緒的代碼
【強制】通過GCD提供的 dispatch_once函數可以簡化代碼,並保證安全執行緒。
+ (DataShareManager *)sharedInstance { static DataShareManager *sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedManager = [[DataShareManager alloc] init]; }); return sharedManager; }
3.8 提供全能的初始化方法
在類中提供一個全能的初始化方法,其他初始化方法均應該調用此方法。
3.9 實現description方法
【強制】實現description 方法返回一個有意義的字串,用以描述該執行個體。
3.10使用清晰而協調的命名方式
【推薦】起名時應遵從標準的Objective-C命名規範,這樣建立的介面更容易為開發人員所理解。方法名要言簡意賅,從左至右讀起來要像個日常用語中的句子。給方法起名時第一要務就是確保風格與你自己的代碼或所要整合的架構相符。
以iOS的UI庫UIKit為列,示範一些命名的慣例:
1. UIView(所有視圖均繼承於此類),開頭兩個字母“UI”是UIKit架構的通用首碼。
2. UIViewController(視圖類UIView)負責繪製視圖
3. UITableView特殊的視圖,顯示表格中的一系列條目
4. UITableViewDelegate 此協議定義了表格視圖與其他對象之間的通訊介面,命名時,把定義“委託介面”(delegate interface)的那個類命名(UITableView)放在前面,後面加上Delegate一詞,這樣讀起來順口。
3.11為私人方法名加首碼
【推薦】給私人方法的名稱加上首碼,這樣可以很容易地將其同公用方法分開。不要單用一個底線做私人方法的首碼,因為這種方法是預留給蘋果公司用的。
3.12 在init 和 dealloc中不要用存取方法訪問執行個體變數
【推薦】在init 和 dealloc 方法被執行時,類的運行時環境不是出於正常狀態的,使用存取方法訪問變數可能會導致不可預料的結果,因此應當在兩個方法內直接存取執行個體變數。
//正例:- (instancetype)init { self = [super init]; if (self) { _bar = [[NSMutableString alloc] init]; } return self;}- (void)dealloc { [_bar release]; [super dealloc];}
3.13 保證NSString在賦值時被複製
【推薦】NSString,在它被傳遞或者賦值時應當保證是一複製(copy)的方式進行的,這樣可以防止在不知情的情況下NSString的值被其他對象修改。
- (void)setFoo:(NSString *)aFoo { _foo = [aFoo copy];}
3.14理解Objective-C的錯誤模型
【推薦】只有發生了可使整個應用程式崩潰的嚴重錯誤時,才應使用異常。在錯誤不那麼嚴重的情況下,可以指派“委託方法”來處理錯誤,也可以把資訊錯誤放在NSError對象裡,經由“輸出參數”返回給調用者。
3.15勿在分類中聲明屬性
【推薦】把封裝資料所用的全部屬性都定義在主介面裡,
在“class-continuation分類”之外的其他分類中,可以定義存取方法,但盡量不要定義屬性。
4. 控制語句
4.1 switch塊內通過break/return來終止
【強制】在一個switch塊內,每個case要麼通過break/return來終止,要麼注釋說明程式將繼續執行到哪一個case為止;在一個switch塊內,都必須包含一個default語句並且放在最後,即使它什麼代碼也沒有。
4.2在if/for/while/switch語句中使用大括弧
【強制】條件陳述式體應該總是被大括弧包圍。儘管有時候你可以不使用大括弧(比如,條件陳述式體只有一行內容),但是這樣做會帶來問題隱患。比如,增加一行代碼時,你可能會誤以為它是 if 語句體裡面的。此外,更危險的是,如果把 if 後面的那行代碼注釋掉,之後的一行代碼會成為 if 語句裡的代碼。
//正例:if (!error) { return success; }
4.3推薦盡量少用else
【推薦】推薦盡量少用else,如下寫法:
if(condition){ ... return obj; } // 接著寫else的商務邏輯代碼;
說明:如果使用要if-else if-else方式表達邏輯,請勿超過3層,不要在條件陳述式中執行複雜的語句
4.4 Objective-C使用YES和NO
【推薦】因為true和false應該只在CoreFoundation,C或C++代碼使用。既然nil解析成NO,所以沒有必要在條件陳述式比較。不要拿某樣東西直接與YES比較,因為YES被定義為1和一個BOOL能被設定為8位。
//正例:if (someObject) {} if (![anotherObject boolValue]) {} //反例:if (someObject == nil) {} if ([anotherObject boolValue] == NO) {} if (isAwesome == YES) {} // Never do this. if (isAwesome == true) {} // Never do this.
4.5 三元操作符
【推薦】當需要提高代碼的清晰性和簡潔性時,三元操作符?:才會使用。單個條件求值常常需要它。多個條件求值時,如果使用if語句或重構成執行個體變數時,代碼會更加易讀。一般來說,最好使用三元操作符是在根據條件來賦值的情況下。
//正例:NSInteger value = 5; result = (value != 0) ? x : y; BOOL isHorizontal = YES; result = isHorizontal ? x : y; //反例:result = a > b ? x = c > d ? c : d : y;
4.6 相等性
【推薦】當你要實現相等性的時候記住這個約定:你需要同時實現isEqual 和 hash方法。如果兩個對象是被isEqual認為相等的,它們的 hash 方法需要返回一樣的值。
4.7方法中需要進行參數校正的情境
【參考】方法中需要進行參數校正的情境:
1) 調用頻次低的方法。
2) 執行時間開銷很大的方法,參數校正時間幾乎可以忽略不計,但如果因為參數錯誤導致中間執行回退,或者錯誤,那得不償失。
3) 需要極高穩定性和可用性的方法。
4) 對外提供的開放介面,不管是DUBBO/API/HTTP介面
5. 注釋
5.1 檔案注釋
【強制】
每一個檔案都必須寫檔案注釋,檔案注釋通常包含
1. 檔案所在模組
2. 作者資訊
3. 曆史版本資訊
4. 著作權資訊
5. 檔案包含的內容,作用
一段良好檔案注釋的例子:
// AFNetworking.h//// Copyright (c) 2013 AFNetworking (http://afnetworking.com/)// // Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.
檔案注釋的格式通常不作要求,能清晰易讀就可以了,但在整個工程中風格要統一。
5.2 屬性注釋
【強制】屬性注釋 使用 /* 注釋/ 的文檔注釋格式。
/** 回複率*/ @property (nonatomic, strong) MTPoiCompareM *replyRate;
5.3 方法集注釋
【強制】
系統有一個內建的方法集注釋代碼塊
5.4 代碼注釋
【強制】方法、函數、類、協議、類別的定義都需要注釋,推薦採用Apple的標準注釋風格,好處是可以在引用的地方alt+點擊自動彈出注釋,非常方便。
有很多可以自動產生注釋格式的外掛程式,推薦使用VVDocumenter:
/** * Get the COPY of cloud device with a given mac address. * * @param macAddress Mac address of the device. * * @return Instance of IPCCloudDevice. */-(IPCCloudDevice *)getCloudDeviceWithMac:(NSString *)macAddress;
5.5 協議、委託的注釋要明確說明其被觸發的條件
/** Delegate - Sent when failed to init connection, like p2p failed. */- (void)initConnectionDidFailed:(IPCConnectHandler *)handler;
6. 其它
6.1 不要使用new方法
【強制】儘管很多時候能用new代替alloc init方法,但這可能會導致調試記憶體時出現不可預料的問題。Cocoa的規範就是使用alloc init方法,使用new會讓一些讀者困惑。
6.2 #import 和 #include
【強制】
當引用的是一個Objective-C或者Objective-C++的標頭檔時,使用#import
當引用的是一個C或者C++的標頭檔時,使用#include,這時必須要保證被引用的檔案提供了保護域(#define guard)
6.3 屬性的安全執行緒
【強制】 定義一個屬性時,編譯器會自動產生安全執行緒的存取方法(Atomic),但這樣會大大降低效能,特別是對於那些需要頻繁存取的屬性來說,是極大的浪費。所以如果定義的屬性不需要線程保護,記得手動添加屬性關鍵字nonatomic來取消編譯器的最佳化。
6.4構建緩衝時選用NSCache而非NSDictionary
【強制】NSCache可以提供優雅的自動刪減功能,同時將NSPurgeableData 與 NSCache搭配使用,可實現自動清除資料的功能。
6.5 精簡initialize與load的實現代碼
【推薦】盡量減少在load方法中執行操作。不要在裡面等待鎖,也不要調用可能會加鎖的方法。無法再編譯器設定的全域常量,可以放在initialize方法裡初始化。
iOS開發代碼規範