1.變量與函數命名
1.1變量命名
對于變量或屬性的命名,首先要統一使用US英語,不要使用漢語拼音代替,命名應簡潔清晰。
統一使用US英語
正確:
UIColor *myColor = [UIColor whiteColor];
錯誤:
UIColor *myColour = [UIColor whiteColor];
命名拼寫不規范
UIColor *naem = @"隔壁老王??";
使用漢語拼音
UIView *qiangmaiButton;
1.2方法命名
對于方法的命名,首先應遵守Objective-C的命名風格,在風格上保持統一
1.方法功能清晰,從左至右讀起來要像日常用語的句子,做到初中生都能讀懂的程度,讓別的開發一眼看出要做的事
2.參數名清晰,不要使用縮寫,避免理解上的晦澀
3.與Foundation/CoreFoundation等框架保持一致,避免命名上的沖突,可以參考下這些框架的命名風格
舉個病栗:
-(void)showTheLoveWithUID:(NSString *)UID ColorNumberStr:(NSString *)colorNumberStr
該方法有以下幾個問題:
1.外部參數名不要大寫開始
2.方法功能不清晰,讀起來不易明白,改為:showTheLoveWithUID:andColorNumber
3.外部參數名要清晰,同時要保證函數名語意上的連貫,而內部參數名要簡潔
改正后:
-(void)showLoveWithUID:(NSString *)UID andColorNumber:(NSString *)colorStr
1.3枚舉類型
枚舉類型使用如下方式定義:
typedef NS_ENUM(NSInteger, ZXGender) {
ZXGenderUnknown = -1,
ZXGenderFemale,
ZXGenderMale,
};
有幾點需要注意:
1.對于枚舉,一般都是有符號數,使用NSInteger
2.枚舉值默認從0開始,盡量指定枚舉從None,Invalid的值開始,該值顯式初始化為-1,這樣可以避免一些地方默認值導致的問題
1.4可選型
typedef NS_ENUM(NSUInteger, ZXUserStateType) {
ZXUserStateTypeSystem = 1<<0, // 系統帳號
ZXUserStateTypeRobot = 1<<1, // 機器人帳號
ZXUserStateTypeManager = 1<<2, // 管理員
};
可選型區別在于每一位都可以表示一種情況,所以需要定義為無符號數
盡量不要使用如下形式:
typedef enum: MyEnumType {
MyEnumType1,
MyEnumType2,
};
2.使用#pragma mark - 對方法進行分類
#pragma mark - Override //重寫方法
- (void)dealloc {}
- (instancetype)init {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Public //公有方法
- (void)publicMethod {}
#pragma mark - Responder //響應事件的方法,包括處理通知的方法
- (IBAction)submitData:(id)sender {}
- (void)handleNotification:(NSNotification *)notification {}
#pragma mark - Delegate //代理實現方法(以相應協議名命名,點擊該協議名可以跳轉到協議聲明的地方)
#pragma mark - Private //私有方法
#pragma mark UI Related Private Methods
- (void)initUI {}
#pragma mark Transaction Related Private Methods
- (void)isNetworkReachable {}
#pragma mark - Setter //Setter方法
- (void)setCustomProperty:(id)value {}
#pragma mark - Getter //Getter方法,通常實現懶加載
- (id)customProperty {}
.m文件中代碼的組織有以下幾點注意:
1.Ovverride 方法都是覆寫的方法,屬于生命周期的重要實現,放在最上面,方便查看,dealloc放在最上面,因為dealloc在功能和閱讀上作用不大,主要用來做釋放檢查
2.Public方法次之,這是些頭文件里面公開出去的接口,放在上面比較醒目些
3.Delegate方法是一些和外部類通信的協議實現,也屬于較重要的邏輯實現
4.Private Method包括一些Helper方法都是類中內部使用的方法,相對而言,邏輯上的重要性較次,放在后面
5.Getter & Setter方法放在最后,都是功能比較單一的方法,基本沒有復雜邏輯
6.#pragma mark - 與 #pragma mark 要正確的配合使用
總之一句話,邏輯上越重要的,位置越靠上,盡量保證在滑動兩屏的情況下能找到這些重要的函數
有些需要注意的地方:
1.不要使用#pragma mark 來注釋,如果方法需要注釋,就在方法上方使用//注釋內容
2.不要使用中文,也沒必要使用中文來添加#pragma mark
3.一些需要注意的點
3.1屬性聲明
比如一個班級學生的成績單:
@interface ClassStudentTranscript : NSObject
@property (nonatomic, stong) NSString *class;
@property (nonatomic, strong) NSNumber *studentCount;
@property (nonatomic, copy) NSMutableArray *studentList;
@end
1.class和studentCount不會改變,使用strong的話,可能強引用的對象在別的地方被修改,這樣的錯誤很難排查
2.對于用copy屬性聲明,這樣在調用setStudentList方法時,傳進來的對象會被copy一份(不管是淺拷貝還是深拷貝),這樣得到的對象就是一個不可變對象,再對該屬性進行增刪操作時,就會出現unrecognized method 錯誤
政治不正確的寫法:
@property (strong, atomic) NSString *property1;
3.2 block的使用
@interface InteractiveStudioView () {
NSString *_address;
}
@property (nonatomic, copy) NSString *name;
@end
dispatch_async(dispatch_get_main_queue(), ^{
self.name = @"隔壁黃總";
});
dispatch_async(dispatch_get_main_queue(), ^{
_address = @"上海盛夏路500號綠岸科創園6F";
});
block在使用時注意引用強引用問題,對于一個屬性self.name 和_address的使用,都會強引用當前self對象。
3.3 if...else 的風格問題
有以下幾種風格:
風格1:
if (success) {
//Do something
} else {
//Do something else
}
風格2:
if(success){
//Do something
}else{
//Do something else
}
風格3:
if (success) {
//Do something
}
else {
//Do something else
}
首先斃掉風格2,注意空格;
風格3的好處:在注釋時不會導致if 語句斷掉,在別的語言里,這也是推薦的風格,很奇怪,Objective-C推薦的居然是風格1,我個人偏向使用風格3的換行方式。
3.4 字面常量(literal)的使用問題
生命一個不可變string或number類型時,盡量使用字面常量的寫法:
NSString *question = @"為啥隔壁王叔叔和大頭兒子一樣頭很大";
NSNumber *age = @(15);
3.5 注意NS開頭的對象初始化方法傳值
對于NS開頭的對象,如果初始化時傳入nil指針,很可能導致crash的發生,在做相關初始化操作時,先檢查參數是否合法,這樣可以避免很多crash問題。