Objective-C編程規范以及建議

本文記錄一下Objective-C編程規范以及一些建議,可能后續會有些修改和補充,至于初衷是最近接手的項目中代碼"有些"凌亂,所以整理了一篇,有一些來自網上,有一些是我平時的代碼風格的吧~

Flag

方法聲明和定義

-或者+和返回類型之間須使用一個空格,括號要同行并有一個空格

方法應該像這樣:

- (void)doSomethingWithString:(NSString *)theString {
  ...
}

如果函數名字太長,可以用冒號對齊,像這樣:

- (void)doSomethingWith:(GTMFoo *)theFoo
                   rect:(NSRect)theRect
               interval:(float)theInterval {
  ...
}

當第一個關鍵字比其它的短時,要保證下一行至少有4個空格的縮進,對齊關鍵字,像這樣:

- (void)short:(GTMFoo *)theFoo
    longKeyword:(NSRect)theRect
    evenLongerKeyword:(float)theInterval {
  ...
}

方法調用

調用時所有參數應該在同一行:

[myObject doFooWith:arg1 name:arg2 error:arg3];

或者每行一個參數,以冒號對齊:

[myObject doFooWith:arg1
               name:arg2
              error:arg3];

方法定義與方法聲明一樣,當關鍵字的長度不足以以冒號對齊時,下一行都要以四個空格進行縮進

[myObj short:arg1
    longKeyword:arg2
    evenLongerKeyword:arg3];

不要使用下面的縮進風格:

[myObject doFooWith:arg1 name:arg2  // some lines with >1 arg
              error:arg3];

[myObject doFooWith:arg1
               name:arg2 error:arg3];

[myObject doFooWith:arg1
          name:arg2  // aligning keywords instead of colons
          error:arg3];

命名

對于易維護的代碼而言,命名規則非常重要。Objective-C 的方法名往往十分長,但代碼塊讀起來就像散文一樣,不需要太多的代碼注釋

當編寫純粹的 Objective-C 代碼時,我們基本遵守標準的 Objective-C naming rules,

文件名

擴展名 文件分類
.h C/C++/Objective-C 的頭文件
.m Objective-C 實現文件
.mm Ojbective-C++ 的實現文件
.cc 純 C++ 的實現文件
.c 純C 的實現文件

類名

類名(以及類別、協議名)應首字母大寫,并以駝峰格式分割單詞

Objective-C 方法名

方法名應該以小寫字母開頭,并混合駝峰格式。每個具名參數也應該以小寫字母開頭
方法名應盡量讀起來就像句子,這表示你應該選擇與方法名連在一起讀起來通順的參數名。(例如,convertPoint:fromRect: 或 replaceCharactersInRange:withString:)。詳情參見 Apple’s Guide to Naming Methods
第二個參數不要and

  • 正確: - (instancetype)initWithWidth:(float)width :(float)height;
  • 不好: - (id)initWithWidth:(float)width andHeight:(float)height;

變量名

應該使用駝峰命名法,變量名盡量能夠代表其自身意思,盡量避免中英文混合命名,中英文混合命名是建議用'_'下劃線分割中英文。
盡量避免如下命名方式

NSDictionary *d0 = [ACGPCacheCenter readFileAtSubDir: HSHomePageSubDirForAD];
NSDictionary *d2 = [ACGPCacheCenter readFileAtSubDir: HSHomePageSubDirForZX];
NSDictionary *d3 = [ACGPCacheCenter readFileAtSubDir: HSHPSubDirForEntry];
NSDictionary *d4 = [ACGPCacheCenter readFileAtSubDir: HSHPSubDirForCopywriting];

循環以及一些生命周期很短、很淺顯易懂的變量可以放開要求,可以使用簡單單字母等等變量名

常量名

常量名(如宏定義、枚舉、靜態局部變量等)應該以小寫字母 k 開頭,使用駝峰格式分隔單詞,如:kInvalidHandle,kWritePerm


注釋

建議注釋不要過多,盡量能夠做到代碼自解釋。與其給類型及變量起一個晦澀難懂的名字,再為它寫注釋,不如直接起一個有意義的名字

關于注釋有以下幾點建議:

.h 文件注釋

.h 文件中 interface 前要加VVDocumenter注釋,例如下面這個類,根據類名根本不知道哪個模塊,做什么的。

@interface HSHPCopywritingCell : HSBaseCollectionViewCell

@end

應改成

/**
 首頁模塊-自選股cell
 */
@interface HSHPCopywritingCell : HSBaseCollectionViewCell

@end

之后在業務代碼中遇到這個類,按住alt鍵鼠標點擊類名就可以查看到類的Description如下:

屬性以及成員變量注釋

屬性、成員變量、枚舉類型的注釋建議用 ///<進行注釋

@property (nonatomic, strong) HSMarketIndexModel *USmodel;      ///< 美股指數model
@property (nonatomic, strong) HSMarketIndexModel *HKmodel;      ///< 港股指數model
@property (nonatomic, strong) HSMarketIndexView *indexView;     ///< 指數view

同樣按住alt鍵鼠標點擊類名也可以查看到類的Description,用/** 美股指數 */ 這種注釋方式也可以看到Description,不過屬性太多可能會不太美觀

代碼塊注釋

善用#pragma mark把代碼進行分類,#pragma mark沒有下劃線,#pragma mark -有下劃線分割

建議用如下類似代碼塊組織代碼:

#pragma mark - ================ LifeCycle =================
- (void)viewDidLoad {
    [self configUI];
    ...
}
- (void) viewWillAppear:(BOOL)animated {
}...

- (void)configUI {
}

#pragma mark - ================ Public Methods =================

#pragma mark ==== 核心公開方法注釋
- (void)somePublicMethod {
}

#pragma mark ==== 核心公開方法注釋2
- (void)somePublicMethod2 {
}

#pragma mark - ================ Private Methods =================

#pragma mark ==== 核心私有方法注釋
- (void)somePrivateMethod {
}

#pragma mark - ================ UITableView Delegate =================

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
}...

#pragma mark - ================ Actions =================

- (void)someButtonClicked {
}

#pragma mark - ================ Getter and Setter =================

- (void)setModelArray:(NSMutableArray *)modelArray {
}

注意:代碼塊的順序應該是由重要到不重要,Getter之類的不重要代碼塊要放在最后,確保別人打開你的類先映入眼簾的是有用的代碼


其他

保持公共API簡單

如果一個函數壓根沒必要公開,就不要這么做,屬性也是一樣,同時對方法進行合理的VVDocumenter注釋,公開屬性以及常量、枚舉盡可能的用///<注釋,除非特別特別簡單的可以省略

關于警告

代碼中遇到警告信息應該盡量解決掉,有一些可能是類型轉換警告,有一些是無用的變量,代碼永遠不會被執行,已廢棄的方法等等,有一點代碼潔癖、對自己的代碼要求嚴格是一件好事

關于廢棄的代碼

項目中遇到廢棄的代碼、沒有用到的類(頭文件)、注釋掉的代碼,除非一定要保留的都要盡量刪掉,保留的寫好注釋,建議用TODO注釋,保留的原因以及相關責任人,以便其他人接手不至于懵逼~


一些建議

定義常量時:多用類型常量,少用#define預處理指令

宏定義沒有類型,有被重復定義風險,影響項目編譯速度。
建議用

static NSString * const kConst = @"Hello";
static const CGFloat kWidth = 10.0;

代替:

#define kConst @"Hello"
#define kWidth 10.0

當定義對外公開的常量的時候,我們一般使用如下定義

//Test.h
extern NSString * const kClassNameconst;
//Test.m
NSString * const kClassNameconst = @"hello";

關于枚舉

推薦使用NS_ENUM和NS_OPTIONS定義

typedef NS_ENUM(NSInteger,TestEnum) {
    MY_INT_CONST = 12345
};

typedef NS_OPTIONS(NSInteger, SelectType) {
    SelectA    = 0,
    SelectB    = 1 << 0,
    SelectC    = 1 << 1,
    SelectD    = 1 << 2
};

在枚舉類型的switch語句中不要實現default分支,有一個好處是,當我們給枚舉增加成員時,編譯器就會提示開發者:switch語句并未處理所有的枚舉

盡量使用簡潔字面量語法

NSArray *animals = @[@"dog", @"pig", @"you"];
Dictionary *dict = @{@"animal":@"tiger", @"phone":@"iPhone 6"};

NSString *dog = animals[0];
NSString *iphone = dict[@"phone"];

屬性的strong、copy

定義可變類型時不要用copy修飾,會留下崩潰隱患

@property (nonatomic, copy) NSMutableArray *mutableArrayOfCopy;   ///< 插入數據時會崩潰

一般NSString 以及NSArray等等不可變類型建議用copy修飾,用strong修飾也沒錯,不過要確定情景是否真的需要strong

結尾:

本文對Objective-C編碼粗略規范以及一些淺顯建議,歡迎大家一起補充完善,共同交流進步,維護增強項目代碼的易讀性,易擴展性,健壯性等等~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容