前言
關于代碼規(guī)范的重要性這里不做過多解釋,能看到這篇文章說明你已經(jīng)開始重視代碼規(guī)范了(代碼規(guī)范看起來是在限制你的自由和發(fā)揮积蜻,其實它是在間接的幫助你變得更優(yōu)秀。)。
適當?shù)拇a規(guī)范和標準絕不是消滅代碼內(nèi)容的創(chuàng)造性闲询、優(yōu)雅性,而是限制過度個性化浅辙,以一種普遍認可的統(tǒng)一方式一起做事扭弧,進而提高工作效率,降低溝通成本记舆。代碼的字里行間流淌著的是軟件和程序員的血液鸽捻,質量的提升是盡可能少踩坑、杜絕踩重復的坑泽腮,切實提升系統(tǒng)穩(wěn)定性御蒲,碼出質量(摘抄自《阿里巴巴Java代碼規(guī)范》)。
根據(jù)約束力度诊赊,暫時把規(guī)范約定為2個等級厚满,分別是 [必須] 和 [建議]。
(一)命名規(guī)范
- 通用命名規(guī)范
Tips:
所有的命名都應該遵循3個基本原則碧磅,即“清晰性”碘箍、“一致性”遵馆、“不要自我指涉”。
[必須] 清晰性:好的命名應該是能自我描述的丰榴。
正例:
removeObject:货邓、[string stringByReplacingOccurrencesOfString:@"1" withString:@"2"]
反例:
remove:(不清楚,要刪除什么四濒?)换况、string.replace("1", "2")(是將"1"替換成"2"還是將"2"替換成"1"?是將第1個"1"替換成"2"還是將所有的"1"都替換成"2")
[必須] 一致性:命名應該和上下文乃至全局保持一致性盗蟆,相同類型或者具有相同作用的變量的命名方式應該相同或類似复隆。
正例:
NSDictionary、NSArray姆涩、NSSet這幾個集合類都是用count來表示數(shù)量而不是一個用count其它的用amount或其他單詞挽拂,這體現(xiàn)了命名的一致性。
@property (readonly) NSUInteger count;
[必須] 禁止自我指涉:命名不要自我指涉骨饿。通知亏栈、掩碼常量等除外(通常指那些可以進行按位運算的枚舉值)。
正例:
NSString
反例:
NSStringObject
[必須] 杜絕過度縮寫宏赘,嚴禁自創(chuàng)縮寫(例如把button縮寫為btn)绒北;國際通用縮寫名稱除外(例如ATM、GPS)察署。
Tips:
你明白這個縮寫的意思不代表其他人也一定會明白闷游,你的代碼可能會被任何人閱讀,而閱讀的人來自不同的地方接受不同的教育不同的文化贴汪,所有建議一般不要亂使用縮寫脐往,只使用那些國際通用縮寫。如果為了縮寫創(chuàng)建一個縮寫對照表只會增加代碼閱讀復雜度扳埂。
正例:
destinationSelection业簿、setBackgroundColor
反例:
destSel、setBgColor
[必須] 杜絕無意義的拼音阳懂,國際通用名稱或者地名人名除外(例如alibaba梅尤、taobao、hangzhou)岩调。
反例:
DaZhePromotion(打折)
[必須] 命名要盡可能的清晰并簡潔巷燥,如果兩者不能兼得,則以清晰為主号枕。
正例:
insertObject:atIndex:
反例:
insert:at:(不清晰缰揪,插入什么?at代表什么?)
[必須] 代碼和注釋中都要避免使用任何語言的種族歧視性詞語堕澄。
正例:
secondary
反例:
slave
[必須] 類名邀跃、協(xié)議名霉咨、函數(shù)名、常量名拍屑、枚舉名等一些全局命名需要添加前綴途戒,前綴需要大于2個字符且全部大寫。
Tips: 系統(tǒng)保留任意兩個字符作為前綴的使用權僵驰,
包括但不限于NS喷斋、UI、CG蒜茴、CF星爪、CA、WK粉私、MK顽腾、CI、NC诺核;前綴若等于2個字符可以考慮添加_抄肖。
正例:
ZT_LoginViewController
反例:
ZTLoginViewController
[必須] 類名、協(xié)議名窖杀、函數(shù)名漓摩、常量名、枚舉名等一些全局命名遵循首字母大寫的駝峰命名方式入客,首個單詞是HTTP這種特殊詞除外管毙。
[必須] 方法名、屬性名等一些非全局命名遵循首字母小寫的駝峰命名方式命名桌硫,首個單詞是HTTP這種特殊詞除外夭咬。
[必須] 成員變量需要以_開頭。
正例:
NSString *_nameString;
[建議] 在給常量或變量命名時鞍泉,盡量將表示類型的名詞放在詞尾皱埠,以提升辨識度。
正例:
nameLabel咖驮、nameString
反例:
name(name是字符串還是什么?)
[建議] 如果模塊、接口训枢、類托修、方法使用了模式,在命名時盡量體現(xiàn)出具體模式恒界。
正例:
OrderFactory睦刃、LoginProxy
[建議] 局部臨時變量命名可以加上標識符作為前綴。
正例:
t_label十酣、t_string(t在這里表示temp)
- 類命名規(guī)范
[必須] 類名命名風格由"前綴+類的名稱+類的類型"3個部分組成涩拙,前綴必須大于2個字符且全部大寫(如果等于2個字符可以添加_)际长;類的名稱遵循首字母大寫駝峰式命名,類的名稱要能表達出該類的功能兴泥;類的類型必須使用全稱工育,嚴禁使用縮寫(例如vc代替viewController,cell代替TableViewCell)搓彻,命名方式和名稱命名一樣首字母大寫如绸。
正例:
WXYZ_LoginViewControler
WXYZ_表示前綴,Login表示該類跟登錄相關旭贬,ViewController表示該類是一個視圖控制器而不是View怔接。
- 方法命名規(guī)范
[必須] 所有方法名稱禁止以new開始。
[必須] 所有方法名稱禁止使用_開始稀轨。
Tips: 系統(tǒng)會使用_開頭命名一些系統(tǒng)私有方法
[必須] 內(nèi)部私有方法需要增加前綴扼脐,前綴需要保持唯一性(例如p_)。
Tips: 給私有方法加前綴有2個好處:
1. 增加辨識度奋刽,提高代碼可讀性谎势。
2. 避免自己的方法無意間覆蓋了系統(tǒng)/框架同名的私有方法。
[必須] 如果方法返回接收者的某個屬性值杨名,那么請直接使用屬性名作為方法名脏榆。
正例:
- (CGSize)cellSize;
反例:
- (CGSize)getCellSize;
[必須] 如果方法間接返回一個或多個值,那么請用"getXXX"命名台谍,這種命名只適用于返回多個數(shù)據(jù)項的情況须喂。
正例:
- (void)getCachedResponseForDataTask:(NSURLSessionDataTask *)dataTask
completionHandler:(void (^) (NSCachedURLResponse * __nullable cachedResponse))completionHandler;
[必須] 方法的每個參數(shù)前都必須添加關鍵字。
正例:
- (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag;
反例:
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
[建議] 參數(shù)之前的單詞盡量能描述參數(shù)的意義趁蕊。
正例:
- (id)viewWithTag:(NSInteger)aTag;
反例:
- (id)taggedView:(int)aTag;
[建議] 請不要使用“and”連接接收者屬性坞生,盡管and讀起來還算順口,但隨著你創(chuàng)建的方法參數(shù)的增加掷伙,這將會帶來一系列的問題是己。
正例:
- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes;
反例:
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
[建議] 如果方法描述了兩個獨立的動作,則可以使用"and"連接起來任柜。
正例:
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
- Protocol命名規(guī)范
[必須] Protocol中的方法命名以觸發(fā)消息的對象名開頭卒废,省略類名前綴并首字母小寫,如果它沒有關聯(lián)任何類則可以忽略這個規(guī)則宙地。
正例:
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
[必須] 除非Protocol方法只有一個參數(shù)摔认,否則冒號需緊跟在類名后面。
正例:
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
- Category命名規(guī)范
[必須] 分類命名也要和類命名一樣添加前綴宅粥。
正例:
UIView (YYAdd)
反例:
UIView (Add)
[必須] 分類中聲明的方法名都要加上前綴参袱。
[建議] Category中盡量不要聲明屬性,能挪盡量挪到主類中聲明。
Tips: 盡管從技術上來講可以在分類中聲明屬性抹蚀,但是這么做需要格外小心剿牺,
因為它很容易出現(xiàn)內(nèi)存上或其他一些問題,而且一旦出現(xiàn)問題很難排查环壤。
[建議] 如果一個類比較復雜晒来,那么建議使用分類組織代碼(可以參考系統(tǒng)的UIView)。
- Notification命名規(guī)范
[必須] Notification的命名風格由"類名前綴" + "通知事件名稱" + "Notification"3個部分組成镐捧。
正例:
UIApplicationDidBecomeActiveNotification
UIApplication表示該通知屬于誰潜索,DidBecomeActive表示該通知的作用,Notification表示它是一個通知懂酱。
[建議] 如果一個類聲明了delegate屬性竹习,通常情況下,這個類的delegate對象應該可以通過實現(xiàn)的delegate方法收到大部分通知消息列牺。
Tips:
例如applicationDidBecomeActive:代理方法和NSApplicationDidBecomeActiveNotification通知(這其實也符合命名規(guī)范的基本原則"一致性")整陌。
- 常量命名規(guī)范
[必須] 如果常量局限于某"編譯單元"之內(nèi),通常在前面加小寫字母k作為前綴瞎领,若常量在全局可見泌辫,通常以類名作為前綴,然后采用首字母大寫的駝峰式命令風格九默。
正例:
// 局部可見
const CGFloat kAnimationDuration = 2.0;
// 全局可見
const CGFloat UIActivityIndicatorViewAnimationDuration = 2.0;
- Exception命名規(guī)范
[必須] 命令規(guī)范和Notification一樣震放,把后綴改為"Exception"即可。
- 文件命名規(guī)范
[必須] 文件名全部小寫驼修。
[必須] 采用_連接單詞殿遂。
[必須] 命名的風格:"模塊_屬性描述",可根據(jù)項目適當增加描述乙各。
正例:
public_back@2x.png
(二)編碼規(guī)范
- 通用編碼規(guī)范
[必須] 如果有使用到CF(Core Foundation)等框架時墨礁,或者是在iOS10以下系統(tǒng)使用通知和KVO時,切記在dealloc方法中釋放對象以及移除通知和監(jiān)聽耳峦。
[必須] 在dealloc方法內(nèi)禁止將self傳遞出去恩静,如果self被retain,到下個runloop周期再釋放則會多次釋放導致crash蹲坷。
反例:
- (void)dealloc {
[self unsafeMethod:self];
}
[必須] 禁止使用過時的方法或類驶乾,應該及時去了解和使用新方法或類。
Tips:
對于過時的方法或類冠句,大都是因為其自身有一些缺陷或BUG才會不建議使用轻掩,使用新方法時建議了解一下為什么廢棄掉舊方法/類。
[必須] 對剪切板的讀取操作必須放在子線程中進行懦底,因為用戶可能在Mac上復制大量數(shù)據(jù)然后通過iCloud同步到iPhone上。
[必須] if、else聚唐、for丐重、while、case等后面必須要有{}杆查,除非后面是簡單的return類型語句扮惦,例如if (xxx) return;。
[必須] 當方法可能會提前return時亲桦,需要要注意對象的釋放問題崖蜜,避免內(nèi)存泄漏。
反例:
CFArrayRef arrayRef = (__bridge CFArrayRef)array;
if (x == YES) return;
CFRelease(arrayRef);
以上代碼如果x等于YES的話那么arrayRef對象就會內(nèi)存泄漏客峭。
[必須] 當使用@try處理異常時豫领,需要要注意對象的釋放問題,避免內(nèi)存泄漏舔琅。
反例:
@try {
CFArrayRef arrayRef = (__bridge CFArrayRef)array;
do some thing……
CFRelease(arrayRef);
} @catch (NSException *exception) {
}
以上代碼如果do some thing……出現(xiàn)異常的話那么arrayRef就會出現(xiàn)內(nèi)存泄漏等恐。
[必須] 聲明常量請使用const類型聲明,禁止使用#define宏定義备蚓。
Tips:
宏定義聲明常量的缺點:
1. 宏定義只是簡單的替換课蔬,缺少編譯檢查,運行期可能會出現(xiàn)溢出或數(shù)據(jù)錯誤等問題郊尝。
2. 宏定義缺少類型二跋,不方便編寫文檔用例。
3. 宏定義可能會被不小心替換流昏。
4. 宏定義無法編寫注釋扎即。
反例:
#define kTime @"10"
if (1 == 2) {
#define kTime @"20"
}
NSLog(@"time = %@", kTime);
以上代碼中的if永遠不會執(zhí)行,但是編譯器也會將kTime替換為@"20"
[建議] 寫一些公共方法時横缔,請盡量使用內(nèi)聯(lián)函數(shù)或者全局函數(shù)而不是宏定義铺遂。
Tips:
函數(shù)不通過對象調(diào)用,所以不會走OC的消息轉發(fā)流程茎刚,效率遠高于方法調(diào)用襟锐;而且函數(shù)會有返回值和參數(shù)類型以及參數(shù)檢查,而這些都是宏定義沒有的膛锭。
正例:
UIKIT_STATIC_INLINE NSString * kNSStringFromInteger(NSInteger a) {
return [NSString stringWithFormat:@"%zd", a];
}
反例:
#define kNSStringFromInteger(a) [NSString stringWithFormat:@"%zd", a]
[必須] UITableView使用self-sizing實現(xiàn)不等高cell時粮坞,請在tableView:cellForRowAtIndexPath:代理方法中給cell設置數(shù)據(jù)而不是tableView:willDisplayCell:forRowAtIndexPath:代理方法中設置數(shù)據(jù)。
[必須] 只在必要的時刻使用懶加載初狰。
Tips:
只在以下三種情況下才能使用懶加載:
1. 對象的創(chuàng)建需要依賴其他對象
2. 對象可能被使用莫杈,也可能不被使用
3. 對象創(chuàng)建比較消耗性能
[建議] 懶加載方法內(nèi)應該只執(zhí)行需要初始化的操作,不應該有其他不必要的邏輯代碼奢入。
[必須] 使用一目運算符時左右兩邊不能有空格筝闹。
正例:
i++、++i、
反例:
i ++关顷、++ i
[必須] 使用二目糊秆、三目運算符時左右兩邊必須有且僅有一個空格。
正例:
1 + 2
反例:
1+2
[必須] 采用4個空格縮進议双,如果要使用Tab字符痘番,請將1個Tab設置成4個空格。
[必須] 使用NSUserDefaults存儲數(shù)據(jù)時禁止調(diào)用synchronize方法平痰,因為系統(tǒng)會在合適的時機將數(shù)據(jù)保存到本地(即使程序閃退等極端情況)汞舱。
[必須] 添加到集合中的對象應該是不可變的,或者在加入之后其哈希碼是不可變的宗雇。
反例:
NSMutableSet *sets = [NSMutableSet set];
NSMutableString *string1 = [NSMutableString stringWithString:@"1"];
[sets addObject:string1];
[sets addObject:@"12"];
[string1 appendString:@"2"];
當 [string1 appendString:@"2"] 執(zhí)行完以后sets對象內(nèi)會包含2個@"12"昂芜。
[必須] 必須使用CGRectGet獲取Frame的各種值,而不是通過frame.的方式獲取逾礁。
Tips:
CGRect t_frame = CGRectMake(-10, -10, -10, -10);
當一個view的frame設置成t_frame后说铃,其坐標會隱式的轉換為CGRectMake(-20, -20, 10, 10)萍膛,因為寬高不可能出現(xiàn)負值径筏;這時通過t_frame.的方式獲取的值都是錯誤的,而CGRectGet會自動幫您處理這些隱式轉換调卑。
正例:
CGRectGetWidth(frame)砾嫉、CGRectGetMinX(frame)幼苛、CGRectGetMaxX(frame)
反例:
frame.size.width、frame.origin.x焕刮、frame.size.width + frame.origin.x
[建議] 單行字符數(shù)限制不超過150個舶沿,超出需要換行(空格可以除外),換行時遵循如下原則:
Tips:
1. 第二行相對第一行縮進4個空格配并,從第三行起不再繼續(xù)縮進括荡。
2. 運算符與下文一起換行。
3. 方法調(diào)用的點符號與下文一起換行溉旋。
正例:
- (void)setImageWithURL:(nullable NSURL *)imageURL
placeholder:(nullable UIImage *)placeholder
options:(YYWebImageOptions)options
progress:(nullable YYWebImageProgressBlock)progress
ransform:(nullable YYWebImageTransformBlock)transform
completion:(nullable YYWebImageCompletionBlock)completion;
[建議] 不可變對象盡量使用copy修飾畸冲,如果重寫使用copy修飾的set方法,請注意調(diào)用copy方法观腊。
[建議] 對于一些體積小并且重要的信息邑闲,不要頻繁的存儲到本地,可以使用NSUserDefaults進行存儲梧油。它會在合適的時機存儲到本地苫耸,這避免了頻繁的寫入操作,而且在某些極端情況下它也能保證數(shù)據(jù)存儲到本地(例如程序閃退等情況)儡陨。
[建議] 在多線程環(huán)境下謹慎使用可變集合褪子,必要時候可以采用加鎖或GCD的同步線程進行保護量淌,或者在訪問可變集合時先將其copy為不可變對象然后再對其訪問。
[建議] 頭文件中盡量不要聲明成員變量而是使用屬性代替褐筛。
[建議] 頭文件中的屬性盡量聲明為只讀类少,可以在實現(xiàn)文件中再將屬性聲明為可讀可寫叙身。
正例:
@interface WXYZModel : NSObject
@property (nonatomic, readonly) NSString *name;
@end
@interface WXYZModel ()
@property (nonatomic, strong) NSString *name;
@end
[建議] 不要使用一個類去維護多個類的內(nèi)容渔扎,例如一個常量類維護所有的常量類,要按常量功能進行歸類信轿,分開維護晃痴。
Tips: 大而全的類,雜亂無章财忽,使用查找功能才能定位到具體位置倘核,不利于理解也不利于維護。
正例:
緩存相關常量類放在CacheCosts下即彪,系統(tǒng)配置相關常量類放在SystemConfigConsts下紧唱。
[建議] 如果大括號內(nèi)為空,則簡潔的寫成{}就行隶校。
[建議] 沒有必要增加多余空格來使上下代碼的等號對齊漏益。
正例:
int a1 = 1;
long a2 = 3;
NSString *a3 = @"";
反例:
int a1 = 1;
long a2 = 3;
NSString *a3 = @"";
[建議] 少用if else,可以使用 if return 替換深胳,if 嵌套最好不超過5層绰疤。
正例:
if (x == 1) {
……
return;
}
if (x == 2) {
……
return;
}
反例:
if (x == 1) {
……
} else if (x == 2) {
……
}
[建議] 盡量避免采用取反邏輯運算符,因為取反邏輯不利于快速理解舞终。
正例:
if (array == nil) {
……
}
反例:
if (!array) {
……
}
[建議] 如果用到了很多協(xié)議轻庆,必要時可以把協(xié)議封裝到一個單獨的頭文件中,這樣做不僅可以減小編譯時間敛劝,還能避免循環(huán)引用余爆。
[建議] 使用Switch枚舉時盡量將所有枚舉類型都列舉出來而不使用default,這樣下次增加枚舉類型時如果Switch沒有處理會有警告信息夸盟。
[建議] 盡量使用字面量語法創(chuàng)建對象蛾方,少用與之等價的方法。
Tips:
OC中的NSArray满俗、NSString转捕、NSDictionay、NSNumber都有與之對應的字面量語法: @[]唆垃、@""五芝、@{}、@()辕万;使用它們有以下優(yōu)點:
1. 簡單易讀枢步,提高代碼的可讀性和可維護性沉删。
2. 使用字面量創(chuàng)建數(shù)組、字典時如果元素里在nil則會拋出異常醉途,而使用arrayWithObjects:這些等價方法創(chuàng)建則會丟失nil后的數(shù)據(jù)矾瑰,拋出異常能讓你知道這里有問題及時修改防止問題在線上發(fā)生。
缺點:
1. 使用字面量創(chuàng)建的對象默認是不可變的隘擎,如果要創(chuàng)建可變對象需要進行mutableCopy操作殴穴。
2. 不支持子類,如果你創(chuàng)建了一個NSString的子類货葬,@""并不會返回你想要的子類對象采幌。
[建議] 頭文件中盡量少引用其他頭文件,盡量使用@class向前聲明震桶,每次引入其他頭文件時問問自己是否必須要這樣做休傍。
[建議] UI控件建議使用weak修飾而不是strong修飾。
- 類編碼規(guī)范
[必須] 如果超類的某個初始化方法不適用于子類蹲姐,那么子類一定要覆寫超類的這個方法并解決該問題或拋出異常磨取。
[建議] 盡量不要使用load類方法,如果必須要使用不能在方法內(nèi)實現(xiàn)復雜邏輯或堵塞線程柴墩。
[建議] 盡量減少繼承忙厌,類的繼承盡量不要超過3層,必要時刻可以考慮用分類拐邪、協(xié)議來代替繼承慰毅。
[建議] 把一些穩(wěn)定的、公共的變量或者方法抽取到父類中扎阶。子類盡量只維持父類所不具備的特性和功能汹胃。
- 方法編碼規(guī)范
[必須] 禁止在init等初始化方法內(nèi)部、getter东臀、setter着饥、dealloc或其他特殊地方使用.語法訪問屬性。
Tips: 當存在繼承關系時使用.語法訪問會因為多態(tài)關系調(diào)用子類的實現(xiàn)方法惰赋,而如果這個時候子類還沒有初始化好或者已經(jīng)釋放了那么可能會出現(xiàn)一些奇怪的問題宰掉。
[必須] 方法參數(shù)在定義和傳入時,逗號后面必須添加一個空格赁濒。
正例:
method(a1, a2, a3);
[建議] 單個方法的行數(shù)建議不超過80行轨奄,注釋、左右大括號拒炎、空行挪拟、回車等除外。
[建議] 在實現(xiàn)文件內(nèi)部也盡量使用.語法訪問屬性而不是使用_直接訪問成員變量來保證風格統(tǒng)一击你。
- Block編碼規(guī)范
[必須] 調(diào)用Block必須判空處理玉组。
Tips:
對于簡單的Block可以使用三目運算進行判空處理谎柄,
例如 !self.block ?: self.block();
[必須] 在Block內(nèi)部使用外部變量時要注意循環(huán)引用的問題。
Tips:
1. 不一定在Block內(nèi)使用self才會循環(huán)引用惯雳,如下情況也會造成循環(huán)引用:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
WXYZ_TitleTableViewCell *cell = ………
cell.refreshTableViewBlock = ^{
[tableView reloadData];
};
return cell;
}
2. Block內(nèi)部是否要使用weak需要看Block本身和weak的這個對象是否存在直接或間接的相互引用朝巫,若無相互引用則不需要使用weak。
3. 如果Block內(nèi)部使用了strong修飾了外部的weak變量石景,那么當使用strong指向成員變量時需要進行判空劈猿,否則會崩潰,參考以下代碼:
__weak typeof(self) weakSelf = self;
cell.refreshTableViewBlock = ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf != nil) {
strongSelf->_name = @"name";
}
};
如果把(strongSelf != nil)的判斷去掉那么可能會崩潰鸵钝。
- 通知編碼規(guī)范
[必須] 在發(fā)送通知時糙臼,請使用userInfo進行傳值,而不是object恩商。
[必須] 通知中心是以同步的方式發(fā)送請求的,所以不要在通知方法做一些復雜的計算必逆,特別是當它處于主線程的時候怠堪,如果想發(fā)送異步通知可以使用NSNotificationQueue。
[建議] 在工程里能不用通知盡量不用通知名眉,通知雖然靈活強大粟矿,但是如果濫用會導致工程質量下降,出現(xiàn)問題時也比較難排查损拢。
- 注釋編碼規(guī)范
[必須] 與其絞盡腦汁寫注釋陌粹,不如想想怎么命名;注釋是起輔助作用的福压,好的命名應該是能自我解釋的掏秩,如果命名可以解釋其作用,并且方法沒有任何副作用或者注意事項荆姆,那么就不用寫注釋蒙幻;注釋應該幫助別人更快的理解該方法的使用和注意事項,如果該方法有需要注意的地方一定要在注釋中體現(xiàn)出來胆筒。
[必須] 當修改了方法實現(xiàn)時需要同步修改注釋內(nèi)容邮破。
[必須] 注釋不要寫的太冗長,要簡單易讀容易理解仆救。
[必須] 注釋的雙斜線和內(nèi)容之間有且僅有一個空格抒和。
正例:
// 這是示例注釋,請注意在雙斜線后有一個空格
- (void)testFunction;
[必須] 對于代碼注釋需謹慎彤蔽,代碼被注釋一般有2種可能摧莽,1) 后續(xù)會恢復此段代碼邏輯; 2) 永久不用铆惑;對于第1種情況需添加相應注釋范嘱,如果沒有注釋信息難以知曉注釋動機送膳,后者建議直接刪除。如果有需要可以通過代碼倉庫查閱歷史代碼丑蛤。
[必須] 使用特殊注釋標記時叠聋,請注明標記人和標記時間,注意及時處理這些標記受裹。
正例:
/**
* @brief 簡要描述
* @author 標明開發(fā)該類模塊的作者
*/
// FIXME: 有bug碌补,需要修改
- (void)testFunction;
[建議] 別給糟糕的代碼加注釋,重構它棉饶。
Tips: 注釋不能美化糟糕的代碼厦章。當企圖使用注釋前,先考慮是否可以通過調(diào)整結構照藻,命名等操作袜啃,消除寫注釋的必要。
(三)工程結構規(guī)范
[必須] 局部使用的常量幸缕、靜態(tài)變量聲明在@interface之前群发。
[必須] @property同一類型的聲明放在一塊,不同類型的聲明用2行空格隔開发乔。
正例:
@interface MineViewController ()
@property (nonatomic, weak) UIView *headView;
@property (nonatomic, weak) UITableView *tableView;
我是換行符熟妓,請忽略
@property (nonatomic, copy) NSArray *dataSourceArray;
[必須] 不同邏輯、不同語義栏尚、不同業(yè)務的代碼之間插入一個空行分隔開以提升可讀性起愈。
正例:
[self createSubviews];
[self createTableview];
[self netRequest];
[必須] 方法歸類
#pragma mark - LifeCycle(生命周期相關的代碼放在最上面)
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
#pragma mark - Public(公開方法)
// code...
// 上空一行
// 下空兩行
#pragma mark - Private(私有方法)
#pragma mark - Override(需要覆蓋父類的方法)
#pragma mark - Notification(通知方法)
#pragma mark - Delegate(Delegate需要實現(xiàn)的方法)
#pragma mark - getter/setter
結語
這只是一篇關于iOS的代碼規(guī)范,所以某些需要和服務端需要統(tǒng)一的規(guī)范(例如錯誤碼)并沒有提到译仗,還有些關于如何編寫安全代碼方面的規(guī)范也只是略微提到抬虽,因為關于如何寫出更安全的代碼應該不屬于代碼規(guī)范層面;歡迎大家提出更好的建議或改進古劲,我也會不斷更新完善斥赋;最后祝大家碼出開心,碼出質量产艾。