移動(dòng)端iOS開發(fā)規(guī)范文檔
序言
- 根據(jù)網(wǎng)上的一些OC編碼規(guī)范整理歸納而成,為了利于項(xiàng)目維護(hù)以及規(guī)范開發(fā)伍纫,促進(jìn)成員之間
Code Review
的效率
函數(shù)的書寫
- 方法長(zhǎng)度建議不超過80行隆夯,如果方法太長(zhǎng)可以考慮抽取其中一部分
- 方法(-钳恕、+)和返回值前面的左括號(hào)間隔一個(gè)空格,方法參數(shù)直接間隔一個(gè)空格蹄衷。每個(gè)方法結(jié)束后需間隔一行來書寫新方法
- (void)applicationDidEnterBackground:(UIApplication *)application
- (void)applicationWillResignActive:(UIApplication *)application
- 如果一個(gè)函數(shù)有特別多的參數(shù)或者名稱特別長(zhǎng)忧额,將其按照:來對(duì)齊分行顯示
-(id)initWithModel:(IPCModle)model
ConnectType:(IPCConnectType)connectType
Resolution:(IPCResolution)resolution
AuthName:(NSString *)authName
Password:(NSString *)password
MAC:(NSString *)mac
AzIp:(NSString *)az_ip
AzDns:(NSString *)az_dns
Token:(NSString *)token
Email:(NSString *)email
Delegate:(id<IPCConnectHandlerDelegate>)delegate;
函數(shù)的調(diào)用
函數(shù)調(diào)用的格式和書寫的差不多,可以按照函數(shù)的長(zhǎng)短選擇寫在一行或者分成多行
//寫在一行
[myObject doFooWith:arg1 name:arg2 error:arg3];
//分行寫愧口,按照 : 對(duì)齊
[myObject doFooWith:arg1
name:arg2
error:arg3];
//第一段名稱過短的話后續(xù)可以進(jìn)行縮進(jìn)
[myObj short:arg1
longKeyword:arg2
evenLongerKeyword:arg3
error:arg4];
閉包
-
block
的右括號(hào)"}"應(yīng)該和調(diào)用block
那行代碼的第一個(gè)非空字符對(duì)齊 -
block
內(nèi)的代碼采用一個(gè)tab
(四個(gè)空格的距離)的縮進(jìn) - 如果
block
過于龐大睦番,應(yīng)該單獨(dú)聲明一個(gè)變量來使用
//分行書寫的block,內(nèi)部使用一個(gè)tab的縮進(jìn)
[operation setCompletionBlock:^{
[self.delegate newDataAvailable];
}];
//使用C語(yǔ)言API調(diào)用的block遵循同樣的書寫規(guī)則
dispatch_async(_fileIOQueue, ^{
NSString* path = [self sessionFilePath];
if (path) {
// ...
}
});
//龐大的block應(yīng)該單獨(dú)定義成變量使用
void (^largeBlock)(void) = ^{
// ...
};
[_operationQueue addOperationWithBlock:largeBlock];
//在一個(gè)調(diào)用中使用多個(gè)block,通過進(jìn)行一個(gè)tab縮進(jìn)
[myObject doSomethingWith:arg1
firstBlock:^(Foo *a) {
// ...
}
secondBlock:^(Bar *b) {
// ...
}
];
命名規(guī)范
項(xiàng)目命名
·項(xiàng)目名都遵循大駝峰命名。例如:AoRiseProject
Bundle Identifier 命名
·Bundle Identifier
:采用反域名命名規(guī)范耍属,全部采用小寫字母托嚣,以域名后綴+公司頂級(jí)域名+應(yīng)用名形式命名,例如:com.rogrand.dianbangbang
類名
類的命名都遵循大駝峰命名厚骗。一般是:前綴 + 功能 + 類型
示启。例如:CPX + Login + ViewController
,在實(shí)際開發(fā)中,一般都會(huì)給工程中所有的類加上屬于本工程的前綴领舰。
常用控件類命名類型對(duì)照表(下表中前綴為:CPX
夫嗓,如果用到下表中沒有列舉出來,請(qǐng)去掉UI首字母冲秽,遵循實(shí)際規(guī)則即可舍咖。)
控件名 | 類型 | 示例 |
---|---|---|
UIViewController | ViewController | CPXBaseViewController |
UView | View | CPXBaseView |
UITableView | TableView | CPXOrderTableView |
UITableViewCell | Cell | CPXOrderListCell |
UIButton | Button | CPXSuccessButton |
UILabel | Label | CPXSuccessLabel |
UIImageView | ImgView | CPXGoodsImgView |
UITextField | TextField | CPXNameTextField |
UITextView | TextView | CPXSuggestTextView |
常量
·宏:小寫k+大駝峰 即為:#define kUserAgeKey @“ageKey”
·全局常量:工程前+綴全大寫,下劃線隔開 即為:extern const NSString MW_USER_AGE_KEY
清晰
- 命名應(yīng)該盡可能的清晰和簡(jiǎn)潔锉桑,但在Objective-C中排霉,清晰比簡(jiǎn)潔更重要
//清晰
insertObject:atIndex:
//不清晰,insert的對(duì)象類型和at的位置屬性沒有說明
insert:at:
- 不要使用單詞的簡(jiǎn)寫刨仑,拼寫出完整的單詞
//清晰
destinationSelection:setBackgroundColor:
//不清晰郑诺,不要使用簡(jiǎn)寫
destSel:setBkgdColor:
- 命名方法或者函數(shù)時(shí)要避免歧義
//有歧義夹姥,是返回sendPort還是send一個(gè)Port?
sendPort
//有歧義辙诞,是返回一個(gè)名字屬性的值還是display一個(gè)name的動(dòng)作辙售?
displayName
命名統(tǒng)一使用駝峰命名法;只采納有廣為人知含義的縮寫飞涂,比如
info
旦部、msg
、UI
较店、HTTP
這類士八。自造的縮寫不被認(rèn)可×撼剩總體的命名原則是清晰和一致婚度,避免歧義。類名需要結(jié)合項(xiàng)目名稱來命名官卡,確保整個(gè)項(xiàng)目中的自定義類的名稱開頭是統(tǒng)一的蝗茁,同樣要確保類名需要大寫字母開頭。
類名命名需結(jié)合功能或者模塊寻咒,并且尾部要帶上該類的類型哮翘,比如
UIViewController的子類命名為JasonIndexViewController。
UIViewController 后綴添加“Controller”
UIView 后綴添加“View”
UIButton 后綴添加“Button"或者"Btn"
UILabel 后綴添加“Label"
一致性
- 整個(gè)工程的命名風(fēng)格要保持一致性毛秘,最好和蘋果SDK的代碼保持統(tǒng)一饭寺。不同類中完成相似功能的方法應(yīng)該叫一樣的名字,比如我們總是用
count
來返回集合的個(gè)數(shù)叫挟,不能在A
類中使用count
而在B
類中使用getNumber
艰匙。
命名方法
- OC的命名方法通常比較長(zhǎng),是為了讓程序有更好的可讀性霞揉,目的是為了可以當(dāng)成一個(gè)句子的形式朗讀出來旬薯,達(dá)到見名知意的效果
- 方法一般以小寫字母打頭,每一個(gè)后續(xù)的單詞首字母大寫适秩,方法名中不應(yīng)該有標(biāo)點(diǎn)符號(hào)(包括下劃線)绊序,有兩個(gè)例外:
- 可以用一些通用的大寫字母縮寫打頭方法,比如
PDF
,TIFF
等秽荞。 - 可以用帶下劃線的前綴來命名私有方法或者類別中的方法骤公。
- 可以用一些通用的大寫字母縮寫打頭方法,比如
如果方法表示讓對(duì)象執(zhí)行一個(gè)動(dòng)作,使用動(dòng)詞打頭來命名扬跋,注意不要使用do
阶捆,does
這種多余的關(guān)鍵字,動(dòng)詞本身的暗示就足夠了:
//動(dòng)詞打頭的方法表示讓對(duì)象執(zhí)行一個(gè)動(dòng)作
- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem;
如果方法是為了獲取對(duì)象的一個(gè)屬性值,直接用屬性名稱來命名這個(gè)方法洒试,注意不要添加get
或者其他的動(dòng)詞前綴:
//正確倍奢,使用屬性名來命名方法
- (NSSize)cellSize;
//錯(cuò)誤,添加了多余的動(dòng)詞前綴
- (NSSize)calcCellSize;
- (NSSize)getCellSize;
對(duì)于有多個(gè)參數(shù)的方法垒棋,務(wù)必在每一個(gè)參數(shù)前都添加關(guān)鍵詞卒煞,關(guān)鍵詞應(yīng)當(dāng)清晰說明參數(shù)的作用:
//正確,保證每個(gè)參數(shù)都有關(guān)鍵詞修飾
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index
//錯(cuò)誤叼架,遺漏關(guān)鍵詞
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
//正確
- (id)viewWithTag:(NSInteger)Tag;
//錯(cuò)誤畔裕,關(guān)鍵詞的作用不清晰
- (id)taggedView:(int)Tag;
不要用and
來連接兩個(gè)參數(shù),通常and
用來表示方法執(zhí)行了兩個(gè)相對(duì)獨(dú)立的操作(從設(shè)計(jì)上來說乖订,這時(shí)候應(yīng)該拆分成兩個(gè)獨(dú)立的方法):
//錯(cuò)誤扮饶,不要使用and來連接參數(shù)
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
//正確,使用and來表示兩個(gè)相對(duì)獨(dú)立的操作
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
命名通知
通知常用于在模塊間傳遞消息乍构,所以通知要盡可能地表示出發(fā)生的事件甜无,通知的命名方式是:
code[觸發(fā)通知的類名] + [ Did | Will ] + [動(dòng)作] + Notification
舉個(gè)栗子
NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification
注釋
文件注釋
- 舉個(gè)栗子
/*******************************************************************************
Copyright (C), 2011-2013, Andrew Min Chang
File name: AMCCommonLib.h
Author: Andrew Chang (Zhang Min)
E-mail: LaplaceZhang@126.com
Description:
This file provide some covenient tool in calling library tools. One can easily include
library headers he wants by declaring the corresponding macros.
I hope this file is not only a header, but also a useful Linux library note.
History:
2012-??-??: On about come date around middle of Year 2012, file created as "commonLib.h"
2012-10-10: Change file name as "AMCCommonLib.h"
2012-12-04: Add UDP support in AMC socket library
2013-01-07: Add basic data type such as "sint8_t"
2013-01-18: Add CFG_LIB_STR_NUM.
2013-01-22: Add CFG_LIB_TIMER.
2013-01-22: Remove CFG_LIB_DATA_TYPE because there is already AMCDataTypes.h
Copyright information:
This file was intended to be under GPL protocol. However, I may use this library
in my work as I am an employee. And my company may require me to keep it secret.
Therefore, this file is neither open source nor under GPL control.
********************************************************************************/
/*************************************************************
* Copyright (c) xxx科技有限公司
* All rights reserved.
*
* 文件名稱: xxx
* 文件標(biāo)識(shí): xxx
* 摘要說明: xxx
*
* 當(dāng)前版本: 1.0.0
* 作 者: CPX
* 更新日期:
* 整理修改:
*
***************************************************************/
文件注釋的格式通常不作要求,能清晰易讀就可以了蜡吧,但在整個(gè)工程中風(fēng)格要統(tǒng)一毫蚓。
代碼注釋
- 方法、函數(shù)昔善、類、協(xié)議畔乙、類別的定義都需要注釋君仆,推薦采用Apple的標(biāo)準(zhǔn)注釋風(fēng)格,好處是可以在引用的地方
alt+command+/
點(diǎn)擊自動(dòng)彈出注釋牲距,非常方便
/**
* 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;
- 協(xié)議返咱、委托的注釋要明確說明其被觸發(fā)的條件
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
UI布局規(guī)范
·建議項(xiàng)目統(tǒng)一使用Masonry
和xib
結(jié)合的方式布局。不允許出現(xiàn)直接設(shè)置frame
的情況牍鞠。如果是純代碼的項(xiàng)目咖摹,不允許出現(xiàn)xib和拉約束的情況。不允許
純storyboard
開發(fā)难述。
· 提取方法萤晴,去除重復(fù)代碼。對(duì)于必要的工具類抽取也很重要胁后,這在以后的項(xiàng)目中是可以重用的店读。
· 盡可能的使用局部變量
· 盡量減少對(duì)變量的重復(fù)計(jì)算
· 盡量在合適的場(chǎng)合使用單例。使用單例可以減輕加載的負(fù)擔(dān)攀芯,縮短加載的時(shí)間屯断,提高加載效率。注意:并不是所有的地方都適用于單例
編碼規(guī)范
- 使用
#pragma mark
來分類方法,參考以下結(jié)構(gòu)殖演,通常將不常用的函數(shù)方法寫在底部氧秘,這里強(qiáng)制要求懶加載必須寫在底部
#pragma mark – Life Cycle
#pragma mark - Events
#pragma mark – Private Methods
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - Custom Delegates
#pragma mark – Getters and Setters
- 枚舉的定義參考系統(tǒng)定義枚舉方式
typedef NS_ENUM(NSUInteger, UISearchBarStyle) {
UISearchBarStyleDefault, // currently UISearchBarStyleProminent
UISearchBarStyleProminent, // used my Mail, Messages and Contacts
UISearchBarStyleMinimal // used by Calendar, Notes and Music
}
-
if
和case
語(yǔ)句,不論if
或者else
下有一個(gè)還是多個(gè)語(yǔ)句,都必須帶上大括號(hào)趴久。同樣case
語(yǔ)句也是如此敏储。
//正確
if (!error) {
return success;
}
//錯(cuò)誤
if (!error)
return success;
或
if (!error) return success;
- 布爾值推薦寫法
if (someObject) {
//...
}
if (![anotherObject boolValue]) {
//...
}
- 當(dāng)需要提高代碼的清晰性和簡(jiǎn)潔性時(shí),三元操作符才會(huì)使用朋鞍。
//推薦寫法
NSInteger value = 5;
result = (value != 0) ? x : y;
BOOL isHorizontal = YES;
result = isHorizontal ? x : y;
//不推薦寫法
result = a > b ? x = c > d ? c : d : y;
-
CGRect
函數(shù)
//推薦寫法
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
//不推薦的寫法
CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
- 當(dāng)使用條件語(yǔ)句編碼時(shí)已添,不要嵌套
if
語(yǔ)句,多個(gè)返回語(yǔ)句也是OK
//推薦寫法
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
//不推薦寫法
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
- 單例模式
//單例對(duì)象應(yīng)該使用線程安全模式來創(chuàng)建共享實(shí)例
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
資源文件規(guī)范
· 全部小寫滥酥,采用下劃線命名法更舞,加前綴區(qū)分。所有的資源文件都需要加上工程前綴(小寫形式)坎吻。
· 命名模式:可加后綴_small
表示小圖,_big
表示大圖缆蝉,邏輯名稱可由多個(gè)單詞加下劃線組成,采用以下規(guī)則:
用途_模塊名_邏輯名稱
用途_模塊名_顏色
用途_邏輯名稱
用途_顏色
說明 | 前綴(工程前綴示例MW) | 示例 |
---|---|---|
按鈕相關(guān) | mw_btn_ | mw_btn_home_normal瘦真、mw_btn_red,mw_btn_red_big |
背景相關(guān) | mw_bg_ | mw_bg_home_header刊头、mw_bg_main |
圖標(biāo)相關(guān) | mw_icon_ | mw_icon_home_location、mw_icon_input |
分割線相關(guān) | mw_div_ | mw_div_home_location诸尽、mw_div_input |
默認(rèn)相關(guān) | mw_def_ | mw_def_home_location原杂、mw_def_input |
版本規(guī)范
· 采用A.B.C
三位數(shù)字命名,比如:1.0.2
您机,當(dāng)有版本更新的時(shí)候穿肄,依據(jù)下面的情況來確定版本號(hào)規(guī)范。
版本號(hào) | 說明 | 示例 |
---|---|---|
A.b.c | 屬于重大更新內(nèi)容 | 1.0.0 -> 2.0.0 |
a.B.c | 屬于小部分更新內(nèi)容 | 1.0.2 -> 1.2.2 |
a.b.C | 屬于補(bǔ)丁更新內(nèi)容 | 1.0.2 -> 1.0.4 |
其他規(guī)范
· 檢測(cè)內(nèi)存泄漏际看∠滩可使用Instruments加上其他第三方工具輔助分析內(nèi)存。