在開(kāi)發(fā)過(guò)程中胀茵,我們不僅要去看別人的代碼,也要讓別人看我們的代碼胁后。那么店读,有一個(gè)良好的編碼習(xí)慣將會(huì)非常重要。下面將會(huì)羅列使用Objective-C來(lái)開(kāi)發(fā)iOS的編碼建議攀芯。
【1】任意函數(shù)長(zhǎng)度不得超過(guò)50行屯断。(其實(shí)很容易就超過(guò)50行,這就要考慮代碼抽取了侣诺。)
【2】任意行代碼不能超過(guò)80字符殖演。(其實(shí)也很容易超過(guò)80字符,可以考慮多行顯示紧武,比如有多個(gè)參數(shù)時(shí)剃氧,可以每個(gè)參數(shù)放一行。)可以在Xcode中設(shè)置超過(guò)80個(gè)字符的提醒阻星,選中“Page guide at column”.設(shè)置完之后就會(huì)在代碼80個(gè)字符處有一條豎線。[Xcode菜單-->Preferences-->Text Editing-->勾選Page guide at column.]
【3】在每個(gè)方法的定義前留白一行,也就是在方法和方法之間留空一行妥箕。
【4】功能相近的方法要放在一起滥酥,并推薦使用#pragma mark - ***來(lái)導(dǎo)航代碼,切分代碼塊畦幢。這樣可以方便函數(shù)的查找坎吻。并且可以使用快捷鍵control+6 來(lái)快速查找方法的位置。
#pragma mark - 生命周期
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
#pragma mark - 代理 MapView
/** 當(dāng)?shù)貓D顯示區(qū)域發(fā)生變化時(shí)觸發(fā) */
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
[self showBussinessedInMapView];
}
【5】二元運(yùn)算符和參數(shù)之間要有一個(gè)空格宇葱,如賦值號(hào)=左右各留一個(gè)空格瘦真。
self.myString = @"235423rew523452345";
【6】一元運(yùn)算符和參數(shù)之間不放置空格,比如黍瞧!非運(yùn)算符诸尽,&按位與,|按位或印颤。
BOOL isOpen = true;
BOOL isClose = !isOpen;
【7】強(qiáng)制類型轉(zhuǎn)換和參數(shù)之間不放置空格您机。
NSString *str3 = (NSString*)self.myString;
【8】長(zhǎng)的變量值應(yīng)該拆分為多行。尤其體現(xiàn)在使用數(shù)組或者字典年局。以下也分別是快速聲明數(shù)組@[]和字典@{}的方法际看。
NSArray *array = @[@"111",
@"2222222222",
@"3333333",
@"wwwwwwwwwwww"
];
NSDictionary *dict = @{@"age":@"20",
@"gender":@"female",
@"isMarried":@"false"
};
【9】盡量使用有意義的名字命名,拒絕使用i,j等無(wú)意義字符命名矢否。類的命名首字母大寫(xiě)仲闽,其他變量的命名首字符小寫(xiě),并使用駝峰式分割單詞僵朗。
【10】盡量減少在代碼中直接使用數(shù)字常量蔼囊,而使用宏定義等方式。如:MAX_NUMBER_PHONE替代8等等衣迷。這樣我們搜索也比較方便畏鼓。
【11】盡量減少代碼中的重復(fù)計(jì)算,比如代碼中多處要使用屏幕寬度壶谒,然后計(jì)算:[[UIScreenmainScreen] bounds].size.width ,很多次云矫,閑得很繁瑣,代碼也冗長(zhǎng)汗菜。不如直接宏定義:
#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
【12】合理使用約定俗成的縮略詞:
alloc:分配让禀;
alt:輪流,交替陨界;
app:應(yīng)用程序巡揍;
calc:計(jì)算;
dealloc:銷毀菌瘪、析構(gòu)腮敌;
func:函數(shù)阱当、方法;
horiz:水平的糜工;
info:信息弊添;
init:初始化;
max:最大的捌木;
min:最小的油坝;
msg:消息;
nib:Interface Builder刨裆;
rect:矩形澈圈;
temp:暫時(shí)的;
vert:垂直的帆啃;
【13】宏定義全部字母大寫(xiě)瞬女。
【14】函數(shù)長(zhǎng)度不要超過(guò)50行,小函數(shù)比大函數(shù)可讀性更強(qiáng)链瓦。函數(shù)的參數(shù)不宜過(guò)多拆魏,零元函數(shù)最好,一元函數(shù)也不錯(cuò)慈俯,高于三元的函數(shù)虛重構(gòu)渤刃。
【15】合理范圍內(nèi)使用鏈?zhǔn)骄幊?
NSString *myName = [[NSString alloc] init];
但是嵌套不宜超過(guò)3層,超過(guò)3層需進(jìn)行重構(gòu)贴膘。
【16】函數(shù)調(diào)用時(shí)所有參數(shù)在同一行卖子。如果參數(shù)過(guò)多,則可以每行一個(gè)參數(shù)刑峡,每個(gè)參數(shù)以冒號(hào)對(duì)齊洋闽。
[[NSNotificationCenter defaultCenter] addObserver:activityIndicator
selector:NSSelectorFromString(@"startActivity")
name:SDWebImageDownloadStartNotification object:nil];
【17】對(duì)傳入?yún)?shù)的保護(hù)或者說(shuō)是否為空的判斷,盡量不要使用if(!obj),而使用NSAssert斷言來(lái)處理突梦。NSAssert是系統(tǒng)定義的宏诫舅。
NSAssert(myName != nil, @"myName參數(shù)為空");
- 如果條件判斷為真,則程序繼續(xù)執(zhí)行宫患。
- 如果判斷條件為假刊懈,則拋出異常,異常內(nèi)容為后面定義的字符串娃闲。
【18】方法參數(shù)名前一般使用"an","the","new"來(lái)進(jìn)行修飾虚汛。如
-(void)setPersonInfo:(NSString*)theID theName:(NSString*)theName theAge:(NSInteger*)theAge
【19】if-else超過(guò)四層的時(shí)候,就要考慮重構(gòu)皇帮,多層的if-else結(jié)構(gòu)很難維護(hù)卷哩。
【20】當(dāng)需要一定條件才執(zhí)行某項(xiàng)操作時(shí),最左邊的應(yīng)該是最重要的代碼属拾,不要將最重要的代碼內(nèi)嵌到if中将谊。如良好的風(fēng)格是:
- (void)someMethod {
if(![someOther boolValue]) {
return;
}
//最重要的代碼寫(xiě)在這里冷溶;
}
反面教材
- (void)someMethod {
if([someOther boolValue]) {
//重要代碼;
}
}
【21】所有的邏輯塊都使用{}花括號(hào)包圍瓢娜,就算只是一行代碼挂洛。
【22】明確指定構(gòu)造函數(shù)礼预,并有適當(dāng)?shù)淖⑨尅?/p>
【23】不要在init方法中把變量或者說(shuō)屬性初始化為0或者nil眠砾,因?yàn)闆](méi)有必要。
【24】UIView的子類初始化的時(shí)候托酸,不要進(jìn)行任何的布局操作褒颈。布局操作應(yīng)該在layoutSubviews里面做;需要重新布局的時(shí)候調(diào)用setNeedsLayout励堡,而不要直接調(diào)用layoutSubviews谷丸。
【25】保持公共API簡(jiǎn)單,也就是保持.h文件簡(jiǎn)單应结。放在.h中聲明的函數(shù)都是會(huì)被公開(kāi)的刨疼,如果根本就沒(méi)必要對(duì)其他類公開(kāi),再不要在.h中聲明鹅龄。OC中的方法都是公有方法揩慕,沒(méi)有私有方法一說(shuō)。
【26】一個(gè)文件只實(shí)現(xiàn)一個(gè)類扮休。同一個(gè)文件中不要有多個(gè)類迎卤。
【27】Protocol單獨(dú)用一個(gè)文件來(lái)創(chuàng)建,盡量不要與相關(guān)類混在一個(gè)文件中玷坠。
【28】在類定義中使用到自己定義類的時(shí)候蜗搔,盡量不要在頭文件中引入自己定義類的頭文件,使用@class替代八堡。而在實(shí)現(xiàn)文件中引入頭文件樟凄。
【29】布局時(shí)盡量使用相對(duì)布局,比如使用子View在父View中的相對(duì)位置兄渺。
【30】代碼折疊缝龄,這個(gè)可能是關(guān)于開(kāi)發(fā)效率的,我也寫(xiě)在編碼規(guī)范中溶耘,因?yàn)檫@個(gè)很有用二拐。Xcode7默認(rèn)沒(méi)有開(kāi)啟代碼折疊,如果你的方法體行數(shù)很長(zhǎng)凳兵,看起來(lái)會(huì)很不方便百新,此時(shí)你就可以把方法“收起來(lái)”,一個(gè)類中的結(jié)構(gòu)就會(huì)很清晰庐扫。開(kāi)啟方法如下:Xcode菜單-->Preferences-->Text Editing-->勾選Code folding ribbon.
【31】推薦方法的第一個(gè)花括號(hào)直接跟在方法體后饭望,而不是另起一行仗哨,這樣可以減少代碼行。
【32】推薦方法體中的第一行留空铅辞,最后一行不留空厌漂,這樣一個(gè)方法就會(huì)比較清晰。如下:
#pragma mark - 生命周期
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- 但是如果該花括號(hào)里面又是一個(gè)if斟珊,for之類的帶花括號(hào)的語(yǔ)句塊苇倡,那么上述的第一行可以不留空。
- 同樣囤踩,如果花括號(hào)內(nèi)第一行是注釋的話旨椒,第一行也可以不留空。注釋也起到了分隔代碼的作用堵漱,看起來(lái)比較清晰综慎。
- 再者,如果花括號(hào)內(nèi)只有一行代碼勤庐,第一行可以不留空示惊。
【33】block中第一行也要留空,同方法體中的第一行留空愉镰,使代碼清晰米罚。
[sheet setCallBackBlock:^(NSInteger index) {
CGRect viewBounds = [ [UIScreen mainScreen] applicationFrame];
if (sheet.cancelButtonIndex == index) {
}
NSLog(@"%@",NSStringFromCGRect(viewBounds));
}];
【34】代表類方法和實(shí)例方法的"+"加號(hào),"-"減號(hào)后需要一個(gè)空格怔揩。這是一個(gè)非常小的細(xì)節(jié)此虑,系統(tǒng)默認(rèn)的方法都是這樣的,我們自己聲明或者實(shí)現(xiàn)一個(gè)方法的時(shí)候也需要這樣
- (void)setCallBackBlock:(blockCallBack)block;
【35】這一條有點(diǎn)像編程經(jīng)驗(yàn)了雳灵,就是為解決某個(gè)問(wèn)題估算時(shí)間类嗤。比如要開(kāi)發(fā)某個(gè)功能糊肠、調(diào)試某個(gè)bug、給自己一個(gè)時(shí)間限制遗锣,如果在這期間不能解決問(wèn)題货裹,那么就去尋求幫助。這既是給自己一個(gè)壓力精偿,也為了不浪費(fèi)時(shí)間弧圆。雖然,這一條其實(shí)很難做到笔咽,我往往由于不甘心而無(wú)限拖延時(shí)間去解決問(wèn)題搔预。
【36】由于提到編程經(jīng)驗(yàn),就不得不提到版本控制叶组。務(wù)必去學(xué)會(huì)SVN或者Git拯田,就算你是獨(dú)立開(kāi)發(fā),也要學(xué)會(huì)控制自己的代碼甩十,當(dāng)然船庇,你要經(jīng)常備份你的代碼吭产。
原文https://github.com/chenyufeng1991
上面都是個(gè)人總結(jié)的,并不一定是標(biāo)準(zhǔn)規(guī)范,如果大家的開(kāi)發(fā)團(tuán)隊(duì)或者公司有自己的編碼規(guī)范鸭轮,當(dāng)然按照?qǐng)F(tuán)隊(duì)的來(lái)
個(gè)人見(jiàn)解:
1.關(guān)于【13】點(diǎn),個(gè)人覺(jué)得還是要根據(jù)實(shí)際需求書(shū)寫(xiě),不一定完全寫(xiě)成大寫(xiě),對(duì)于國(guó)人來(lái)說(shuō),小寫(xiě)更便于閱讀,不過(guò)肯定不可以全小寫(xiě)
比如SDWebImage中的宏定義
#define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage"
2.關(guān)于【10】點(diǎn),盡量減少在代碼中直接使用數(shù)字常量臣淤,而使用宏定義等方式;宏定義太多會(huì)導(dǎo)致工程編譯速度變慢!個(gè)人感覺(jué)窃爷,如果多處用到一個(gè)數(shù)字邑蒋,定義個(gè)宏好一些,方便管理;如果只有一定地方用到,那就沒(méi)必要了,可以選擇常量
比如SDWebImage源碼示例
static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week
NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain";
if (frameDuration < 0.011f) {
frameDuration = 0.100f;
}
if (timeoutInterval == 0.0) {
timeoutInterval = 15.0;
}
3.關(guān)于【33】點(diǎn),進(jìn)行擴(kuò)展,@interface聲明屬性之間要空一格,即使只有一個(gè)屬性,
SDWebImage源碼示例:
@interface聲明屬性之間要空一格,計(jì)算只有一個(gè)屬性, SDWebImage源碼示例:
@interface SDWebImageDownloader ()
@property (strong, nonatomic) NSOperationQueue *downloadQueue;
@property (strong, nonatomic) NSMutableDictionary *URLCallbacks;
@property (strong, nonatomic) NSMutableDictionary *HTTPHeaders;
// This queue is used to serialize the handling of the network responses of all the download operation in a single queue
@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue;
@end
4.關(guān)于【4】點(diǎn),進(jìn)行擴(kuò)展,聲明屬性,如果屬性比較多,可對(duì)屬性進(jìn)行分類,方便查看
注釋樣式
/*
***********************************************************************
*
* ?????? 當(dāng)你疼的時(shí)候,你才會(huì)開(kāi)始真正的行動(dòng) ??????
* 人類的大腦是很貪心的,總是想同時(shí)干很多事情
* 我們又很著急,總想在比較短的時(shí)間見(jiàn)效;
* 大多數(shù)人失敗并非個(gè)人能力不行
* 而是因?yàn)樗麄儗⒕Ψ稚⒃谔嗟哪繕?biāo)上面了;
***********************************************************************
*/
// >>>>>>>>>>>>>>>>>>>>>>>>>> 數(shù)據(jù)源接口
/** 本地圖片數(shù)組 */
@property (nonatomic, strong) NSArray *localizationImageNamesGroup;
/** 網(wǎng)絡(luò)圖片 url string 數(shù)組 */
@property (nonatomic, strong) NSArray *imageURLStringsGroup;
/** 每張圖片對(duì)應(yīng)要顯示的文字?jǐn)?shù)組 */
@property (nonatomic, strong) NSArray *titlesGroup;
// >>>>>>>>>>>>>>>>>>>>>>>>> 滾動(dòng)控制接口
/** 自動(dòng)滾動(dòng)間隔時(shí)間,默認(rèn)2s */
@property (nonatomic, assign) CGFloat autoScrollTimeInterval;
/** 是否無(wú)限循環(huán),默認(rèn)Yes */
@property(nonatomic,assign) BOOL infiniteLoop;
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 自定義樣式接口
/** 輪播圖片的ContentMode,默認(rèn)為 UIViewContentModeScaleToFill */
@property (nonatomic, assign) UIViewContentMode bannerImageViewContentMode;
/** 占位圖吞鸭,用于網(wǎng)絡(luò)未加載到圖片時(shí) */
@property (nonatomic, strong) UIImage *placeholderImage;