iOS代碼規(guī)范

iOS Coding Guidelines(代碼指南)

版本號(hào) 編寫人 日期
2.0 搶手的哥 2019-06-05

一、命名基礎(chǔ)

駝峰命名

  • 針對(duì)屬性、變量、方法等均采用小寫字母開頭的駝峰命名準(zhǔn)則。
  • 針對(duì)類、枚舉、宏等均采用大寫字母開頭的駝峰命名準(zhǔn)則。

清晰性

  • 最好是既清晰又簡(jiǎn)短,但不要為簡(jiǎn)短而喪失清晰性

  • 示例:removeObject:

  • 反例:remove

  • 名稱通常不縮寫,即使名稱很長(zhǎng),也要拼寫完全

  • 示例:destinationSelection

  • 反例:destSel

我們盡可能遵守 Apple 的命名約定,其推薦使用長(zhǎng)的,描述性強(qiáng)的方法和變量名,使其閱讀起來(lái)更加清晰易懂。不能隨意使用縮寫,導(dǎo)致他人閱讀代碼困難。

一致性

  • 盡可能使用與 Cocoa 編程接口命名保持一致的名稱。如果你不太確定某個(gè)命名的一致性,請(qǐng)瀏覽一下頭文件。
  • 在使用多態(tài)方法的類中,命名的一致性非常重要。在不同類中實(shí)現(xiàn)相同功能的方法應(yīng)該具有相同的名稱
  • 示例:- (NSInteger)tag
  • 示例:- (void)setStringValue:(NSString *)

前綴

前綴是名稱的重要組成部分,它們可以區(qū)分應(yīng)用的功能范疇。前綴可以防止與第三方開發(fā)者之間的命名沖突

  • 前綴有規(guī)定的格式。它由兩到三個(gè)大寫字符組成,不能使用下劃線與子前綴
  • 命名 class, protocol, struct, 函數(shù),常量時(shí)使用前綴;
  • 命名成員方法時(shí)不使用前綴,因?yàn)榉椒ㄒ呀?jīng)在它所在類的命名空間中;
  • 同理,命名結(jié)構(gòu)體字段時(shí)也不使用前綴

二、方法命名【強(qiáng)制】

一般性規(guī)則

為方法命名時(shí),請(qǐng)考慮如下一些一般性規(guī)則:

  • 小寫第一個(gè)單詞的首字符,大寫隨后單詞的首字符,不使用前綴。有兩種例外情況:
  1. 方法名以廣為人知的大寫字母縮略詞(如 TIFF or PDF)開頭
  2. 私有方法可以使用統(tǒng)一的前綴來(lái)分組和辨識(shí)
  • 表示對(duì)象行為的方法,名稱以動(dòng)詞開頭

  • 示例:- (void)invokeWithTarget:(id)target:

  • 示例:- (void)selectTabViewItem:(NSTableViewItem *)tableViewItem

  • 如果方法返回方法接收者的某個(gè)屬性,直接用屬性名稱命名。不要使用 get,除非是間接返回一個(gè)或多個(gè)值。

  • 示例:- (NSSize)cellSize

  • 反例:- (NSSize)getCellSize

  • 不要使用 and 來(lái)連接用屬性作參數(shù)關(guān)鍵字

  • 示例:- (NSInteger)runModalForDirectory:(NSString *)path file:(NSString *)name

  • 反例:- (NSInteger)runModalForDirectory:(NSString *)path andFile:(NSString *)name

方法參數(shù)

命名方法參數(shù)時(shí)要考慮如下規(guī)則:

  • 如同方法名,參數(shù)名小寫第一個(gè)單詞的首字符,大寫后繼單詞的首字符。

  • 示例:removeObject:(id)anObject

  • 不要在參數(shù)名中使用 pointer 或 ptr,讓參數(shù)的類型來(lái)說明它是指針

  • 避免使用 one, two,…,作為參數(shù)名

  • 避免為節(jié)省幾個(gè)字符而縮寫

三、實(shí)例變量與數(shù)據(jù)類型命名【強(qiáng)制】

描述性的單詞(有意義)+ 變量類型

私有變量:

私有變量放在 .m 文件中聲明 以 _ 開頭,第一個(gè)單詞首字母小寫
例子:NSString * _somePrivateVariable

屬性變量:

正例:@property (nonatomic, strong) UILabel *nameLabel;
注意nonatomic和strong之間有一個(gè)空格,*號(hào)之前有空格,之后沒有
反例:@property(strong,nonatomic)UILabel * lab;

如果實(shí)例變量別設(shè)計(jì)為可被訪問的,確保編寫了訪問方法并注意讀寫權(quán)限。

枚舉常量

  • 使用枚舉來(lái)定義一組相關(guān)的整數(shù)常量
typedef NS_ENUM(NSInteger, NSMatrixMode) { 
    NSRadioModeMatrix       = 0, 
    NSHighlightModeMatrix   = 1,
    NSListModeMatrix        = 2, 
    NSTrackModeMatrix       = 3
};

其他常量

  • 通常不使用 #define 來(lái)創(chuàng)建常量。如上面所述,整數(shù)常量請(qǐng)使用枚舉。
  • 使用大寫字母來(lái)定義預(yù)處理編譯宏。如:#ifdef DEBUG
  • 為 notification 名定義大駝峰字符串常量,從而能夠利用編譯器的拼寫檢查,減少書寫錯(cuò)誤。

四、圖片資源命名

模塊名+功能名+控件名+狀態(tài)
photoBrowser_btn_selected photoBrowser_btn_unselected

五、可接受的縮略語(yǔ)

在設(shè)計(jì)編程接口時(shí),通常名稱不要縮寫。下面列出的縮寫要么是固定下來(lái)的要么是過去被廣泛使用的,所以可以繼續(xù)使用。關(guān)于縮寫有一些額外的注意事項(xiàng):

  • 標(biāo)準(zhǔn) C 庫(kù)中長(zhǎng)期使用的縮寫形式是可以接受的。如:”alloc”, “getc”
  • 你可以在參數(shù)名中更自由地使用縮寫。如: imageRep, col(column), obj, otherWin

常見的縮寫

縮寫 含義 縮寫 含義
alloc Allocate alt Alternate
app Application calc Calculate
dealloc dealloc func Function
horiz Horizontal info Information
init Initialize int Integer
max Maximum min Minimum
msg Message nib Interface Builder archive
pboard Pasteboard rect Rectangle
Rep Representation temp Temporary
vert Vertical

補(bǔ)充的縮寫

縮寫 含義 縮寫 含義
idx Index btn Button
proj Project pro Professional
pwd Password pic Picture
str String img Image
VC ViewController

五、編碼格式

星號(hào)(*)位置

  • 定義一個(gè)對(duì)象時(shí),*靠近變量

  • 示例:NSString *userName;

統(tǒng)一的ViewController模板(代碼縮進(jìn)、Method進(jìn)行分組、大括號(hào)寫法)

  • import引用分組劃分
  • 使用property與局部變量,不使用用全局變量(不能顯性區(qū)分作用域)
  • 空格與換行建議(參照iOS SDK API)
  • 方法功能區(qū)域性劃分
#import "GMBaseViewController.h"
/**
 HomePage
 */
@interface HomePageViewController : GMBaseViewController
/** 項(xiàng)目Id */
@property (nonatomic, copy) NSString *projectId;
@end
#import "HomePageViewController.h"
#import "HomePageTableViewCell"     //View
#import "HomePageListRequest"       //Model數(shù)據(jù)類
#import "ProjectViewController"     //非本頁(yè)面所用

@interface GMHPViewController ()

@end

@implementation GMHPViewController
#pragma mark - LifeCycle
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupView];
    [self loadData];
}

#pragma mark - Custom Methods
- (void)setupView {

}
#pragma mark - Event Response


#pragma mark - Data && Net
- (void)loadData {
   
}

#pragma mark - UITableViewDataSource && UITableViewDelegate

#pragma mark - CustomDelegate

#pragma mark - Getter && Setter

條件語(yǔ)句

  • 條件判斷語(yǔ)句執(zhí)行主體不管是 if 里面還是 else 里面都必須要使用大括號(hào)包住, 即使代碼是一行的情況(Apple SSL/TLS gotofail)。for 循環(huán)同樣。
  • if-else中,else不另起一行,與if的反括號(hào)在同一行,如下段代碼所示,注意else前后均有空格。
  • switch-case中,建議所有case和default后的代碼塊均用{}包裹。
if(success){
    ...
} else {
    ...
}

for(int i = 0 ; i < 10 ; i++){
    ...
}

單一原則

  • 每個(gè)函數(shù)的職責(zé)都應(yīng)該劃分明確(如類一樣)

模型解析(MJExtension)

+ (NSDictionary *)mj_replacedKeyFromPropertyName {
    return @{@"Id" : @"id"};
}

+ (NSDictionary *)mj_objectClassInArray {
    return @{@“block” : @"GMBlockModel"};
}

其他

  • 子類重寫父類方法一般需先調(diào)用父類方法
- (void)viewDidLoad {
    [super viewDidLoad];
    ...
}
  • 單模塊多頁(yè)面可新建模塊Header類,統(tǒng)一導(dǎo)入共用類,設(shè)定常量等。非全局不可定義在PCH

六、代碼注釋

優(yōu)秀的代碼大部分是可以自描述的,我們完全可以用代碼本身來(lái)表達(dá)它到底在干什么,而不需要注釋的輔助。
但并不是說一定不需要寫注釋,有以下三種情況需要編寫注釋:

  • 公共接口(注釋要告訴閱讀代碼的人,當(dāng)前類能實(shí)現(xiàn)什么功能,譬如:基礎(chǔ)類、工具類)
  • 涉及到比較深層專業(yè)知識(shí)及業(yè)務(wù)邏輯的代碼(注釋要體現(xiàn)出實(shí)現(xiàn)原理和思想)
  • 容易產(chǎn)生歧義的代碼(但是嚴(yán)格來(lái)說,容易讓人產(chǎn)生歧義的代碼是不允許存在的)

import注釋

如果有一個(gè)以上的import語(yǔ)句,就對(duì)這些語(yǔ)句進(jìn)行分組,每個(gè)分組的注釋是可選的。

屬性注釋

/** 注釋 */
@property (nonatomic, strong) UIView *headerView;

枚舉注釋

typedef NS_ENUM(NSInteger, RefreshDateType) {
    /** 新建 */
    RefreshDateTypeTaskMain    = 1,
    /** 編輯 */
    RefreshDateTypeEdit,
    /** 重派 */
    RefreshDateTypeAssign,
    /** 新建子任務(wù) */
    RefreshDateTypeSubTask,
    /** 任務(wù)派發(fā)(進(jìn)度管理模塊) */
    RefreshDateTypeTaskDis,
    /** 任務(wù)變更(進(jìn)度管理模塊) */
    RefreshDateTypeTaskChanged,
};

方法聲明注釋

公開接口,重要的方法,分類,以及協(xié)議都應(yīng)該伴隨注釋。方法的注釋使用Xcode自帶注釋快捷鍵:Commond+option+/或者///,這兩種注釋方式可被XcodeQuick Help識(shí)別

/**
 <#Description#>

 @param tableView <#tableView description#>
 @param section <#section description#>
 @return <#return value description#>
 */
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
   ...
}

///<#Description#>
- (void)getUserInfo {
    ...
}

<font size=2 color=#4A7EC0>參考文檔:</font>Apple Coding Guidelines for Cocoa

七、其他事項(xiàng)

1.【推薦】條件過多、過長(zhǎng)時(shí)應(yīng)該換行

if  ( condition1 &&
      condition2 &&
      condition3 ) {
}

2.【強(qiáng)制】二元運(yùn)算符與變量之間必須有空格

width = 5 + 5; 
height = width * 2;
length = width + height;
for (int i = 0; i < 10; i++)

3.【強(qiáng)制】NSArray泛型

如果NSArray中存儲(chǔ)數(shù)據(jù)類型是統(tǒng)一的,必須如下使用

/** modelArray  */
@property (nonatomic, strong) NSArray <GCBModel *> *modelArray;

4.【強(qiáng)制】block循環(huán)引用問題<特別關(guān)注>

__weak_self;
[selectPerVC setSingleResultBlock:^(ContactModel *resultModel) {
     __strong_self;
}];

5【強(qiáng)制】枚舉使用

項(xiàng)目中兩個(gè)以上的區(qū)分邏輯要使用枚舉,使用枚舉值賦值的時(shí)候不能使用枚舉的值(1、2、3… 等)
正例:self.dataType = RefreshDateTypeTaskMain;
反例:self.dataType = 1;

6【強(qiáng)制】加載xib

xib名稱用NSStringFromClass(),避免書寫錯(cuò)誤
正例:[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([DXRecommendTagVCell class]) bundle:nil] forCellReuseIdentifier:ID];
反例:[self.tableView registerNib:[UINib nibWithNibName:@"DXRecommendTagVCell" bundle:nil] forCellReuseIdentifier:ID];

7【強(qiáng)制】三目運(yùn)算符

三目運(yùn)算符使用時(shí)注意?和:空格
正例:NSString *string = model.isSelected ? @"已選中" : @"未選中";
禁止連續(xù)使用三目運(yùn)算符
反例:return indexPath.row == 0 ? 109 : indexPath.row == 1 ? 138 : indexPath.row == 10 ? 45 : indexPath.row == 11 ? [PublicPhotoBrowserView getCollecHeiImageCount:self.taskModel.imgsArray.count remainCount:9 - self.taskModel.filesArray.count width: ScreenW - 30 detail:NO]+[PublicPhotoBrowserView publicPhotoGetFilesHeight:self.taskModel.filesArray.count singleHeight:0] : 55

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

相關(guān)閱讀更多精彩內(nèi)容

  • iOS代碼規(guī)范 一、前言 本規(guī)范基于Google Objective-C Style Guide和百度Object...
    CoderHw閱讀 963評(píng)論 0 7
  • 概要 Objective-C是一門面向?qū)ο蟮膭?dòng)態(tài)編程語(yǔ)言,主要用于編寫iOS和Mac應(yīng)用程序。關(guān)于Objectiv...
    DreamMmMmM閱讀 1,275評(píng)論 0 7
  • -------------------------------------編碼原則----------------...
    yanhooIT閱讀 1,078評(píng)論 0 11
  • 一、命名規(guī)范 命名規(guī)則對(duì)于維護(hù)代碼來(lái)說是非常重要的,。Objective-C方法名往往很長(zhǎng),不過這也有好處,讓很多...
    jmsYang閱讀 449評(píng)論 0 0
  • 一、命名規(guī)范 1、統(tǒng)一要求含義清楚,盡量做到不需要注釋也能了解其作用,若做不到,就加注釋,使用全稱,不使用縮寫。 ...
    Untils閱讀 622評(píng)論 0 0

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