移動(dòng)端iOS開發(fā)規(guī)范文檔

移動(dòng)端iOS開發(fā)規(guī)范文檔

序言

  • 根據(jù)網(wǎng)上的一些OC編碼規(guī)范整理歸納而成,為了利于項(xiàng)目維護(hù)以及規(guī)范開發(fā),促進(jìn)成員之間Code Review的效率

函數(shù)的書寫

  • 方法長度建議不超過80行,如果方法太長可以考慮抽取其中一部分
  • 方法(-、+)和返回值前面的左括號間隔一個(gè)空格,方法參數(shù)直接間隔一個(gè)空格。每個(gè)方法結(jié)束后需間隔一行來書寫新方法
- (void)applicationDidEnterBackground:(UIApplication *)application

- (void)applicationWillResignActive:(UIApplication *)application 
  • 如果一個(gè)函數(shù)有特別多的參數(shù)或者名稱特別長,將其按照:來對齊分行顯示
-(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ù)的長短選擇寫在一行或者分成多行

//寫在一行
[myObject doFooWith:arg1 name:arg2 error:arg3];
 
//分行寫,按照 : 對齊
[myObject doFooWith:arg1
               name:arg2
              error:arg3];
 
//第一段名稱過短的話后續(xù)可以進(jìn)行縮進(jìn)
[myObj short:arg1
          longKeyword:arg2
    evenLongerKeyword:arg3
                error:arg4];

閉包

  • block的右括號"}"應(yīng)該和調(diào)用block那行代碼的第一個(gè)非空字符對齊
  • 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語言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ī)范,全部采用小寫字母,以域名后綴+公司頂級域名+應(yīng)用名形式命名,例如:com.rogrand.dianbangbang

類名

類的命名都遵循大駝峰命名。一般是:前綴 + 功能 + 類型。例如:CPX + Login + ViewController,在實(shí)際開發(fā)中,一般都會(huì)給工程中所有的類加上屬于本工程的前綴
常用控件類命名類型對照表(下表中前綴為:CPX,如果用到下表中沒有列舉出來,請去掉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)該盡可能的清晰和簡潔,但在Objective-C中,清晰比簡潔更重要
//清晰
insertObject:atIndex:
//不清晰,insert的對象類型和at的位置屬性沒有說明
insert:at:
  • 不要使用單詞的簡寫,拼寫出完整的單詞
//清晰
destinationSelection:setBackgroundColor:
 
//不清晰,不要使用簡寫
destSel:setBkgdColor:
  • 命名方法或者函數(shù)時(shí)要避免歧義
//有歧義,是返回sendPort還是send一個(gè)Port?
sendPort
 
//有歧義,是返回一個(gè)名字屬性的值還是display一個(gè)name的動(dòng)作?
displayName
  • 命名統(tǒng)一使用駝峰命名法;只采納有廣為人知含義的縮寫,比如info、msgUI、HTTP這類。自造的縮寫不被認(rèn)可??傮w的命名原則是清晰和一致,避免歧義。

  • 類名需要結(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的命名方法通常比較長,是為了讓程序有更好的可讀性,目的是為了可以當(dāng)成一個(gè)句子的形式朗讀出來,達(dá)到見名知意的效果
  • 方法一般以小寫字母打頭,每一個(gè)后續(xù)的單詞首字母大寫,方法名中不應(yīng)該有標(biāo)點(diǎn)符號(包括下劃線),有兩個(gè)例外:
    • 可以用一些通用的大寫字母縮寫打頭方法,比如PDF,TIFF等。
    • 可以用帶下劃線的前綴來命名私有方法或者類別中的方法。

如果方法表示讓對象執(zhí)行一個(gè)動(dòng)作,使用動(dòng)詞打頭來命名,注意不要使用do,does這種多余的關(guān)鍵字,動(dòng)詞本身的暗示就足夠了:

//動(dòng)詞打頭的方法表示讓對象執(zhí)行一個(gè)動(dòng)作
- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem;

如果方法是為了獲取對象的一個(gè)屬性值,直接用屬性名稱來命名這個(gè)方法,注意不要添加get或者其他的動(dòng)詞前綴:

//正確,使用屬性名來命名方法
- (NSSize)cellSize;
 
//錯(cuò)誤,添加了多余的動(dòng)詞前綴
- (NSSize)calcCellSize;
- (NSSize)getCellSize;

對于有多個(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è)相對獨(dú)立的操作(從設(shè)計(jì)上來說,這時(shí)候應(yīng)該拆分成兩個(gè)獨(dú)立的方法):

//錯(cuò)誤,不要使用and來連接參數(shù)
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
//正確,使用and來表示兩個(gè)相對獨(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)識:        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)一使用Masonryxib結(jié)合的方式布局。不允許出現(xiàn)直接設(shè)置frame的情況。如果是純代碼的項(xiàng)目,不允許出現(xiàn)xib和拉約束的情況。不允許storyboard開發(fā)。
· 提取方法,去除重復(fù)代碼。對于必要的工具類抽取也很重要,這在以后的項(xiàng)目中是可以重用的。
· 盡可能的使用局部變量
· 盡量減少對變量的重復(fù)計(jì)算
· 盡量在合適的場合使用單例。使用單例可以減輕加載的負(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
}
  • ifcase語句,不論if或者else下有一個(gè)還是多個(gè)語句,都必須帶上大括號。同樣case語句也是如此。
//正確
if (!error) {
  return success;
}
//錯(cuò)誤
if (!error)
  return success;
或  
if (!error) return success;
  • 布爾值推薦寫法
if (someObject) {
    //...
}
if (![anotherObject boolValue]) {
    //...
}
  • 當(dāng)需要提高代碼的清晰性和簡潔性時(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)使用條件語句編碼時(shí),不要嵌套if語句,多個(gè)返回語句也是OK
//推薦寫法
- (void)someMethod {
  if (![someOther boolValue]) {
    return;
  }

  //Do something important
}

//不推薦寫法
- (void)someMethod {
  if ([someOther boolValue]) {
    //Do something important
  }
}

  • 單例模式
//單例對象應(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ù)下面的情況來確定版本號規(guī)范。

版本號 說明 示例
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ī)范

· 檢測內(nèi)存泄漏。可使用Instruments加上其他第三方工具輔助分析內(nèi)存。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容