前言
為什么要制定一套Objective-C在iOS APP開發(fā)的規(guī)范要求?我們都知道贪惹,一款APP開發(fā)出來之后媳维,還有冗長的維護和迭代過程底扳,而且在APP的開發(fā)過程中铸抑,絕大多數(shù)都是團隊開發(fā),如果在這期間沒有一套統(tǒng)一衷模、規(guī)范的開發(fā)標準鹊汛,就很難保證代碼風格的一致性,可讀性降低 阱冶,團隊開發(fā) 和 后期維護 都會帶比較嚴重的后果刁憋。
如果在APP的開發(fā)過程中都以這個標準去執(zhí)行,代碼的可讀性熙揍、開發(fā)期間的溝通职祷、后期維護都會非常順暢。
開發(fā)標準(規(guī)范)制定依據(jù)
既然是標準,可能就會有人質(zhì)疑了有梆,你制定的這套標準有什么依據(jù)是尖?
首先這個標準不是由個人制定,也不是由哪一個團隊制定泥耀,而是根據(jù)Apple官方文檔以及Xcode 中提供的一些SourceCode 為參考來制定的饺汹。
當然還有很多認可度極高的文檔:
The Objective-C Programming Language
Cocoa Fundamentals Guid
Coding Guidelines for Cocoa
iOS App Programming Guide
規(guī)范正文
一 . 關(guān)于命名
命名要求含義清楚,盡量做到不需要注釋也能了解其作用痰催;
不要偷懶兜辞,勤加注釋;
命名使用英語夸溶,不要使用拼音逸吵、數(shù)字。
1. 類的命名
大駝峰式命名:每個單詞的首字母都采用大寫字母缝裁。
前綴以約定的標志性字母開頭扫皱,中間以功能英文單詞命名,再加上全名后綴(不得簡寫)捷绑。
例一:GTHomePageViewController // Controller層控制器類名
例二:GTUserInfoModel //Model層類名
例三:GTNewsListsTableViewCell //View層TableViewCell的命名
例三:GTAlertSheetViewDelegate //代理方法中Delegate的命名
例三:GTAlertSheetViewDateSource //代理方法中DateSource的命名
2. Foundation成員變量的命名
小駝峰式命名:第一個單詞以小寫字母開始韩脑,后面的單詞的首字母全部大寫。
例一: .m 文件中聲明的私有變量
{
NSString * _somePrivateVariable;
}
例二:property變量
@property (nonatomic, strong) NSString *userName;
3. UIKit成員變量的命名
小駝峰式命名:第一個單詞以小寫字母開始粹污,后面的單詞的首字母全部大寫段多。此外命名必須是 描述性的單詞+變量類型,一目了然壮吩。
變量類型運行使用通用的縮寫进苍,若縮寫不是公認的,不推薦鸭叙。
例一: .m 文件中聲明的私有變量
{
UILabel * _nameLabel;
UIButton * _nameBtn
}
例二:property變量
@property (nonatomic, strong) UILabel * nameLb;
@property (nonatomic, strong) UIButton * nameButton;
4. 宏命名
- 情況一:全部大寫琅捏,單詞間用 _ 分隔。[不帶參數(shù)] [不推薦使用]
- 情況二:以字母 k 開頭递雀,后面遵循大駝峰命名。[不帶參數(shù)]
- 情況三:以字母 k 開頭蚀浆,小駝峰命名缀程。[帶參數(shù)]
推薦 使用 [情況二] 和 [情況三]。
例一:情況一
#define THIS_IS_AN_MACRO @"THIS_IS_AN_MACRO"
例二:情況二
#define kWidth self.frame.size.width
例三:情況三
#define kGetImageUrl(url) [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",kBaseUrl,url]]
5. Xib的命名
Xib文件的命名與其對應的.h文件保持相同
二. 枚舉Enum
為什么要把枚舉單獨拿出來說市俊?
我們都知道杨凑,代碼中很多需要根據(jù)狀態(tài)值來進行分類的,比如服務器傳來一個狀態(tài)參數(shù)1 摆昧、2撩满、 3等等值,1代表交易成功、2代表已經(jīng)付款伺帘、3代表未付款等等昭躺,這里我們在代碼編寫過程中直接用if else 來分類就low爆了,不僅代碼的可讀性低伪嫁,而且維護起來非常不便领炫。而且如果狀態(tài)值代表的意義還有改變的,需要來怎么去處理张咳?如果開發(fā)初期就規(guī)定使用枚舉帝洪,這些問題就會很容易的解決。
- 必須使用 NS_ENUM 或者 NS_OPTIONS
- Enum類型的命名與類的命名規(guī)則一致
- Enum中枚舉內(nèi)容的命名需要以該Enum類型名稱開頭
typedef NS_ENUM(NSUInteger, ShareUISelcetIndex) {
ShareUISelcetIndexDefault = SSDKPlatformTypeUnknown, // 默認
ShareUISelcetIndexWechatFriend = SSDKPlatformSubTypeWechatSession, // 微信好友
ShareUISelcetIndexWechatGroup = SSDKPlatformSubTypeWechatTimeline, //微信朋友圈
ShareUISelcetIndexQQFriend = SSDKPlatformSubTypeQQFriend, //QQ好友
ShareUISelcetIndexQQZone = SSDKPlatformSubTypeQZone, //QQ空間
ShareUISelcetIndexSina= SSDKPlatformTypeSinaWeibo, //新浪
ShareUISelcetIndexRefresh, // 刷新
ShareUISelcetIndexCopyToPad, // 復制到剪切板
};
三. 方法的命名
1.普通方法的命名
方法使用小駝峰法命名脚猾。
一個規(guī)范的方法讀起來應該像一句完整的話(OC語言的風格)葱峡。讀過之后便知函數(shù)的作用。
執(zhí)行性的方法應該以動詞開頭龙助,小寫字母開頭砰奕。
返回性的方法應該以返回的內(nèi)容開頭。
例一:執(zhí)行性
-(void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
例二:返回性
-(instancetype)arrayWithArray:(NSArray *)array;
2.Delegate方法的命名
- 類的實例必須為回調(diào)方法的參數(shù)之一;
- 回調(diào)方法的參數(shù)只有類自己的情況泌参,方法名要符合實際含義;
- 以類的名字開頭(回調(diào)方法存在兩個以上參數(shù)的情況)以表明此方法是屬于哪個類的;
- 推薦使用did和will通知Delegate已經(jīng)發(fā)生的變化或?qū)⒁l(fā)生的變化.
類的實例必須為回調(diào)方法的參數(shù)之一
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
回調(diào)方法的參數(shù)只有類自己的情況脆淹,方法名要符合實際含義;
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
以類的名字開頭(回調(diào)方法存在兩個以上參數(shù)的情況)以表明此方法是屬于哪個類的
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
推薦使用did和will通知Delegate已經(jīng)發(fā)生的變化或?qū)⒁l(fā)生的變化.
-(NSIndexPath*)tableView:(UITableView*)tableView willSelectRowAtIndexPath:(NSIndexPath*)indexPath;
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath;
3. 對方法進行分組(#pragma mark -)
使用 #pragma mark - 方式對類的方法進行分組,會使代碼分區(qū)沽一,看起來非常賞心悅目盖溺。
如圖:
4. 代碼縮進
[小技巧]直接強文件中的代碼剪切,再復制粘貼進來铣缠。 Xcode 會自動對代碼進行縮進處理烘嘱。
Method與Method之間至少空一行,最好是最多也只空一行蝗蛙。
5. 大括號寫法
- 左括號跟在第一行后邊
- 任何需要寫大括號的部分蝇庭,不得省略
錯誤示例:
- (void)wrongExample{
BOOL someCondition = YES;
if (someCondition)
NSLog(@"this is wrong!!!");
}
規(guī)范示例:
- (void)rightExample{
BOOL someCondition = YES;
if (someCondition){
NSLog(@"this is wrong!!!");
}
}
四. 注釋
1. 屬性注釋
- 推薦使用 注釋統(tǒng)一采用文檔注釋方式:/** description */ ,即Xcode 8 提供的快捷鍵注釋捡硅。Xcode 7 版本采用這種注釋在調(diào)用該屬性的時候哮内,會提示出這個描述,但現(xiàn)在Xcode 8 似乎沒有壮韭。
- 其他注釋 // Description
@interface ShareUIView : UIView
/**
block one
*/
@property (nonatomic,copy) void(^cellClickblock)(ShareUISelcetIndex index);
@property (nonatomic,copy) void(^cellPushblock)(ShareUISelcetIndex index); // block two
@end
2. 方法聲明注釋
- 推薦使用 Xcode 8 提供的快捷鍵注釋北发。
/**
單例模式
*
@return 單例對象
*/
+(LeeAlertSheetView *)sharedInstacne;
/**
* 創(chuàng)建提示框(Alert 可變參數(shù)版)
*
* @param title 標題
* @param message 提示內(nèi)容
* @param cancelTitle 取消按鈕(無操作,為nil則只顯示一個按鈕)
* @param vc VC iOS8及其以后會用到
* @param confirm 點擊按鈕的回調(diào)(取消按鈕的Index是cancelIndex -1)
* @param buttonTitles 按鈕(為nil,默認為"確定",傳參數(shù)時必須以nil結(jié)尾,否則會崩潰)
*/
- (void)showAlert:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm buttonTitles:(NSString *)buttonTitles, ... NS_REQUIRES_NIL_TERMINATION;
五. 三目運算符
我們直接就開始舉個栗子了
- (void)rightExample{
BOOL someCondition = YES;
if (someCondition){
self.myView.alpha = 0.5;
}else{
self.myView.alpha = 0.1;
}
}
這里如果用三目運算符怎么寫喷屋?
- (void)rightExample{
self.myView.alpha = someCondition ? 0.5: 0.1
}
六. 多使用常量(const)琳拨,代替宏(define)
可以參考這篇文章iOS 宏(define)與常量(const)的正確使用
比如定義一個常量又不想被修改應該這樣:
static NSString * const HSCoder = @"漢斯哈哈哈";
static NSString * const collectionCellIdentifier = @"ShareUICollectionViewCell";
七. 其他
- 在屬性命名中,如果類的全名太長屯曹,可以使用一些縮寫狱庇,但這些縮寫必須是大家公認惊畏,沒有任何歧義的。(比如:nav密任,bg颜启,btn,lb批什,tf等)农曲。
- 在函數(shù)命名中,推薦使用一些經(jīng)典的操作應該使用約定的動詞驻债,如initWith,insert,remove,replace,add等等乳规。
- 對于類的method: 左括號另起一行寫(遵循蘋果官方文檔)。這一要求可以使用合呐,但不強制使用暮的,具體可以根據(jù)團隊開發(fā)要求來限定,因為比如我們創(chuàng)建一個UIViewController淌实,里面的方法均沒有執(zhí)行這一要求冻辩,所以我們也不強制執(zhí)行。
如有紕漏拆祈,歡迎留言狂噴
沒有傷害恨闪,就沒有進步。
- QQ 375701847放坏。