@(〓〓 iOS-Objective-C精選)[Objective-C 文章精選]
- 作者: Liwx
- 郵箱: 1032282633@qq.com
目錄
- 01.優(yōu)秀的Objective-C編碼風(fēng)格指南
- 參考文檔
- 目錄
- 代碼結(jié)構(gòu)
- 代碼格式化
- 注釋
- 命名規(guī)范
- 類名/類別名/協(xié)議
- 方法
- 函數(shù)
- 常量
- 變量
- 通知和異常
- 布爾值
- 條件語(yǔ)句
- 初始化方法
- CGRect函數(shù)
- Xcode工程結(jié)構(gòu)
- Just for fun
參考文檔
此編碼規(guī)范在制定的時(shí)候參考和借鑒了以下這些優(yōu)秀的Objective-C編碼風(fēng)格指南:
- Coding Guidelines for Cocoa
- Objective-C Style Guide
- Daniel's Objective-C Coding Style Guidelines
- raywenderlich.com Objective-C style guide
目錄
代碼結(jié)構(gòu)
實(shí)現(xiàn)文件中的代碼結(jié)構(gòu)闻牡,提倡以下約定:
用
#pragma mark -
將函數(shù)或方法按功能進(jìn)行分組。-
dealloc方法放到實(shí)現(xiàn)文件的最頂部塑娇。
這樣是為了時(shí)刻提醒你要記得釋放相關(guān)資源澈侠。
-
delgate或協(xié)議相關(guān)方法放到一般內(nèi)容之后。
#pragma mark - Lifecycle - (void)dealloc {} - (instancetype)init {} - (void)viewDidLoad {} - (void)viewWillAppear:(BOOL)animated {} - (void)didReceiveMemoryWarning {} #pragma mark - Custom Accessors - (void)setCustomProperty:(id)value {} - (id)customProperty {} #pragma mark - Protocol conformance #pragma mark - UITextFieldDelegate #pragma mark - UITableViewDataSource #pragma mark - UITableViewDelegate #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone {} #pragma mark - NSObject - (NSString *)description {}
代碼格式化
-
只用空格縮進(jìn)埋酬,1個(gè)TAB = 4個(gè)空格字符
在XCode->Preferences->Text Editing->Indentation中進(jìn)行如下設(shè)置:
- Prefer indent using: 選擇 Spaces
- Tab key:選擇 Intents in leading whitespace
- 所有需要填寫空格數(shù)目的地方都設(shè)置成4個(gè)
ps. 設(shè)置成4個(gè)哨啃,是因?yàn)閄code的默認(rèn)縮進(jìn)是4個(gè)空格。大量遺留代碼也都是采用的縮進(jìn)4個(gè)空格写妥。
-
建議:每行代碼的長(zhǎng)度最多不超過(guò)100個(gè)字符
為了防止代碼過(guò)長(zhǎng)拳球,也為了兼顧Macbook上的排版效果,將每行長(zhǎng)度限制成100個(gè)字符珍特。
勾選XCode->Preferences->Text Editing->Editing祝峻,并將長(zhǎng)度設(shè)置成100個(gè)字符來(lái)打開(kāi)行寬指示。
ps. Google倡導(dǎo)的每行80個(gè)字符有點(diǎn)少扎筒,會(huì)帶來(lái)更頻繁的換行莱找,因此增加到100個(gè)字符。
-
建議:嘗試將單個(gè)函數(shù)或方法的實(shí)現(xiàn)代碼控制在30行內(nèi)
如果某個(gè)函數(shù)或方法的實(shí)現(xiàn)代碼過(guò)長(zhǎng)嗜桌,可以考量下是否可以將代碼拆分成幾個(gè)小的擁有單一功能的方法奥溺。
ps. 30行是在13寸macbook上XCode用14號(hào)字體時(shí),恰好可以讓一個(gè)函數(shù)的代碼做到整屏完全顯示的行數(shù)骨宠。
-
建議:將單個(gè)實(shí)現(xiàn)文件里的代碼行數(shù)控制在500~600行內(nèi)
為了簡(jiǎn)潔和便于閱讀浮定,建議將單個(gè)實(shí)現(xiàn)文件的代碼行數(shù)控制在500~600行以內(nèi)最好。
當(dāng)接近或超過(guò)800行時(shí)层亿,就應(yīng)當(dāng)開(kāi)始考慮分割實(shí)現(xiàn)文件了桦卒。
最好不要出現(xiàn)代碼超過(guò)1000行的實(shí)現(xiàn)文件。
我們一般傾向于認(rèn)為單個(gè)文件代碼行數(shù)越長(zhǎng)匿又,代碼結(jié)構(gòu)就越不好方灾。而且,翻代碼翻的手軟啊琳省。
可以使用Objective-C的Category特性將實(shí)現(xiàn)文件歸類分割成幾個(gè)相對(duì)輕量級(jí)的實(shí)現(xiàn)文件迎吵。
可以勾選上XCode->Preferences->Text Editing->Editing中的Line numbers躲撰,開(kāi)啟行號(hào)提示。
-
實(shí)現(xiàn)文件中击费,函數(shù)實(shí)現(xiàn)或方法實(shí)現(xiàn)之間必須至少有一行空行
沒(méi)有空行拢蛋,代碼過(guò)長(zhǎng)后,全粘在一起蔫巩,很影響閱讀吏祸。
//禁止的
- (void)loadView {
//load view...
}
- (void)viewDidLoad {
[super viewDidLoad];
//Do Something...
}
//正確的
- (void)loadView {
//load view...
}
- (void)viewDidLoad {
[super viewDidLoad];
//Do Something...
}
-
重載父類方法時(shí)外冀,遇到必須調(diào)用父類方法時(shí)。調(diào)用super的代碼和重載的代碼之間留一行空行。
這樣做是為了便于區(qū)分出對(duì)super的調(diào)用粹湃。
通常在iOS SDK中诡必,有許多方法在重載的時(shí)候赊颠,都要求調(diào)用super侣监。有時(shí)候忘記調(diào)用super就會(huì)出現(xiàn)行為怪異的bug。
因此這里要求將調(diào)用super的代碼區(qū)隔開(kāi)來(lái)歪沃,方便閱讀嗦锐,也方便查找是否忘記了對(duì)super的調(diào)用。- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; //空一行沪曙,將super方法的調(diào)用和重載代碼區(qū)隔開(kāi)來(lái)奕污。 [NSObject cancelPreviousPerformRequestsWithTarget:self]; }
-
實(shí)現(xiàn)文件中,函數(shù)體的左花括號(hào)不另起一行液走,和函數(shù)名同行碳默,并且和函數(shù)名之間保持1個(gè)空格
此條是為了和XCode6.1模板生成的文件的代碼風(fēng)格保持一致。
//贊成的 - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } //不贊成的 - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }
-
其他地方(
if
/else
/while
/switch
等)缘眶,左花括號(hào)不單獨(dú)另起一行嘱根。左花括號(hào)后面緊接著的代碼塊超過(guò)5行后,代碼塊和括號(hào)之間要有一行空行巷懈;代碼塊小于5行可以不空行此條是為了和XCode自動(dòng)代碼補(bǔ)全生成的代碼風(fēng)格保持一致儿子。
```objc
//贊成的
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
if (somethCondtion) {
//DO Something.
}
}
//不贊成的
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
if (somethCondtion)
{
//DO Something
}
}
```
- 建議: if/else中,else與上一條分支語(yǔ)句的右括號(hào)之間需要換行
此條是為了防止else和上一個(gè)分支的代碼塊挨在一起砸喻,影響閱讀,所以建議要換行蒋譬。
換行后割岛,也便于快速定位到else分支。
//贊成的
if (a > 0) {
//Do Something
}
else {
//Do Something
}
//不贊成的
if (a > 0) {
//Do Something
} else {
//Do Something
}
如果需要手動(dòng)使用
@synthesize
或@dynamic
犯助,每行只能定義一個(gè)屬性-
方法調(diào)用中癣漆,如果block參數(shù)需要換行時(shí),block結(jié)尾的花括弧要和聲明block那一行的第一個(gè)字符對(duì)齊
[operation setCompletionBlock:^{ [self.delegate newDataAvailable]; }];
-
如果方法調(diào)用中部分的代碼過(guò)長(zhǎng)剂买,造成內(nèi)嵌的block代碼縮進(jìn)過(guò)長(zhǎng)惠爽,可以適當(dāng)?shù)脑黾邮謩?dòng)換行癌蓖,以減少代碼縮進(jìn)
//如以下代碼在loadWindowWithCompletionBlock前加了手動(dòng)換行,是被提倡的: [[SessionService sharedService] loadWindowWithCompletionBlock:^(SessionWindow *window) { if (window) { [self windowDidLoad:window]; } else { [self errorLoadingWindow]; } }];
注釋
-
注釋應(yīng)該盡量保持簡(jiǎn)潔婚肆,代碼應(yīng)該盡量達(dá)到能自我解釋的程度
當(dāng)然用于生成文檔的注釋除外租副,用于生成文檔的注釋要盡量詳細(xì),特別是你的接口可能有副作用的時(shí)候较性,要注釋清楚用僧。
注釋必須和代碼保持同步。不要出現(xiàn)代碼修改了赞咙,注釋不更新的情況
-
對(duì)函數(shù)或API接口的注釋责循,都采用Javadoc風(fēng)格規(guī)范
因?yàn)閄Code5支持直接將Javadoc風(fēng)格的注釋生成文檔。
也有用于添加Javadoc風(fēng)格注釋的XCode插件:VVDocumenter-Xcode
命名規(guī)范
無(wú)論什么情況下攀操,都要盡量堅(jiān)持蘋果的命名規(guī)范院仿,特別是涉及到內(nèi)存管理規(guī)則時(shí)
這里的"內(nèi)存管理規(guī)則",強(qiáng)調(diào)的是底層Core Foundation框架中速和,名字帶Create或Copy的函數(shù)歹垫,返回的對(duì)象,你要負(fù)責(zé)它的釋放健芭。
類名/類別名/協(xié)議
類名县钥、類別名字及協(xié)議名字,都采用大駝峰式命名規(guī)則
-
文件名要能反映出它所包含的類的名稱
如:NSString.h 和 NSString.m 包含了NSString類的定義和實(shí)現(xiàn)
-
Category的文件名要包含它所擴(kuò)展的那個(gè)類的名稱慈迈,并且類別名稱要盡量能夠描述它的功能
UIImage+Resize.h 或 UIImage+TintColor.h
-
在面向特定應(yīng)用的代碼中若贮,類名盡量避免使用前綴,每個(gè)類都使用相同的前綴會(huì)影響可讀性
面向特定應(yīng)用的代碼痒留,指那些只會(huì)在一個(gè)項(xiàng)目中使用的代碼谴麦,不會(huì)被用于其他項(xiàng)目中的代碼。
-
在面向多應(yīng)用的代碼中伸头,類名要使用前綴匾效,防止命名沖突
面向多應(yīng)用的代碼,指那些會(huì)被多個(gè)項(xiàng)目共同使用的代碼恤磷。
比如CRKit這個(gè)類庫(kù)中面哼,使用了CR前綴。
-
建議:前綴至少使用三個(gè)字母
此條是為了減少命名沖突扫步。但鑒于目前流行前綴大多都是兩個(gè)字母魔策,所以此條不做強(qiáng)制要求
-
協(xié)議聲明或定義中,類型標(biāo)識(shí)符河胎、協(xié)議名稱闯袒、尖括號(hào)之間不留空格
@interface MyProtocoledClass : NSObject<NSWindowDelegate> { @private id<MyFancyDelegate> _delegate; } - (void)setDelegate:(id<MyFancyDelegate>)aDelegate; @end
方法
-
方法名和參數(shù)名都采用小駝峰式命名規(guī)則。
如:- (BOOL)isFileExistedAtPath:(NSString *)filePath;
-
方法聲明中,-/+和返回值類型之間要空1個(gè)空格政敢,方法名和參數(shù)類型之間以及參數(shù)類型和參數(shù)名之間不留空格
- (void)invokeWithTarget:(id)target; //正確 - (void)invokeWithTarget: (id)target; //錯(cuò)誤 - (void)invokeWithTarget:(id) target; //錯(cuò)誤 - (void)invokeWithTarget: (id) target; //錯(cuò)誤
-
方法聲明中其徙,參數(shù)過(guò)多超過(guò)一行時(shí),可以增加手動(dòng)換行喷户,使每個(gè)參數(shù)占用一行唾那,以冒號(hào)對(duì)齊
- (void)doSomethingWith:(GTMFoo *)theFoo rect:(NSRect)theRect interval:(float)theInterval;
-
方法名第一段比其他部分短時(shí),每個(gè)參數(shù)占用一行摩骨,每行至少縮進(jìn)4個(gè)空格通贞,盡量保持參數(shù)以冒號(hào)對(duì)齊
同時(shí)選中多行代碼,用快捷鍵"command+["或"command+]"可以減少或增加縮進(jìn)恼五。
- (void)short:(GTMFoo *)theFoo longKeyword:(NSRect)theRect evenLongerKeyword:(float)theInterval error:(NSError **)theError;
-
方法名和參數(shù)名應(yīng)該盡量讀起來(lái)像一句話昌罩。具體參見(jiàn)蘋果的方法名命名規(guī)范
如:convertPoint:fromRect: 或者 replaceCharactersInRange:withString:
-
當(dāng)各個(gè)參數(shù)是接收者的某個(gè)屬性時(shí),方法名中不要用"and"來(lái)連接
//贊成的 - (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; //不贊成的 - (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
-
如果方法名描述了兩種不同的動(dòng)作灾馒,要使用"and"來(lái)連接
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
-
getter方法的方法名應(yīng)該和變量名字相同茎用,不允許使用"get"前綴
本規(guī)則僅適用于Objective-C,C++使用C++的相關(guān)規(guī)范
- (id)delegate; // 正確 - (id)getDelegate; //禁止
-
類私有方法以下劃線開(kāi)頭
如:
- (void)_startDownloadFiles;
Objective-C里面沒(méi)有真正嚴(yán)格意義上私有方法睬罗。這里所說(shuō)的"私有方法"指那些不需要公開(kāi)的轨功、只會(huì)在實(shí)現(xiàn)文件中使用的方法。
這樣做的好處是容达,可以直觀的快速區(qū)別實(shí)現(xiàn)文件中的私有方法和公有方法古涧。
這樣做會(huì)很便于重構(gòu)。如果某個(gè)方法廢棄了花盐,需要移除的時(shí)候羡滑,發(fā)現(xiàn)它是以下劃線開(kāi)頭的,那么就可以確定這個(gè)方法是私有的算芯,只會(huì)在這個(gè)實(shí)現(xiàn)文件中被用到柒昏。那么直接在該實(shí)現(xiàn)文件搜索這個(gè)方法的名字,然后清理掉搜索到的地方就可以了熙揍。不必再在整個(gè)項(xiàng)目中查找是否沒(méi)有清理干凈职祷。
根據(jù)蘋果的建議,這種做法可能覆蓋掉父類的私有方法届囚。
但是目前還沒(méi)有遇到過(guò)這種情況有梆,而且我們認(rèn)為此條約定帶來(lái)的好處遠(yuǎn)遠(yuǎn)大于它潛在的危險(xiǎn),因此仍然推行這條約定意系。
函數(shù)
函數(shù)指純C函數(shù)淳梦,這里提倡與蘋果風(fēng)格類似的約定。
函數(shù)名采用大駝峰式命名方式昔字,參數(shù)名采用小駝峰式命名方式
-
如果函數(shù)和某個(gè)特定類型相關(guān),那么函數(shù)名前綴要和類型前綴一樣
如
CGRectMake()
、CGContextCreate()
等
常量
-
創(chuàng)建NSString, NSDictionary, NSArray, 以及NSNumber等常量時(shí)作郭,使用Literals語(yǔ)法
//例如: NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"]; NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"}; NSNumber *shouldUseLiterals = @YES; NSNumber *buildingZIPCode = @10018; //而不是: NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil]; NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil]; NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES]; NSNumber *ZIPCode = [NSNumber numberWithInteger:10018];
-
定義枚舉常量時(shí)陨囊,使用NS_ENUM或NS_OPTIONS
NS_ENUM和NS_OPTIONS都提供了類型檢查
//例如: typedef NS_ENUM(NSUInteger, PPNavBarButtonColor) { PPNavBarButtonColorBlack, PPNavBarButtonColorGreen, PPNavBarButtonColorDefault = PPNavBarButtonColorBlack }; typedef NS_OPTIONS(NSUInteger, PSTCollectionViewScrollPosition) { PSTCollectionViewScrollPositionNone = 0, PSTCollectionViewScrollPositionTop = 1 << 0, PSTCollectionViewScrollPositionCenteredVertically = 1 << 1, PSTCollectionViewScrollPositionBottom = 1 << 2, PSTCollectionViewScrollPositionLeft = 1 << 3, PSTCollectionViewScrollPositionCenteredHorizontally = 1 << 4, PSTCollectionViewScrollPositionRight = 1 << 5 };
定義常量時(shí),除非明確的需要將常量當(dāng)成宏使用夹攒,否則優(yōu)先使用
const
蜘醋,而非#define
-
只在某一個(gè)特定文件里面使用的常量,用static
static關(guān)鍵字保證變量只有文件作用域咏尝,可以避免變量名重名造成的鏈接錯(cuò)誤問(wèn)題压语。
比如:
static CGFloat const RWImageThumbnailHeight = 50.0;
-
常量名以小寫k開(kāi)頭,采用首字母大寫的方式來(lái)分割單詞
//例如: const int kNumberOfFiles = 12; NSString *const kUserKey = @"kUserKey"; enum DisplayTinge { kDisplayTingeGreen = 1, kDisplayTingeBlue = 2 };
-
和特定類型相關(guān)的枚舉常量使用類名作為前綴编检,而不用小寫k開(kāi)頭胎食。
typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) { UICollectionViewScrollPositionNone = 0, UICollectionViewScrollPositionTop = 1 << 0, UICollectionViewScrollPositionCenteredVertically = 1 << 1, UICollectionViewScrollPositionBottom = 1 << 2, UICollectionViewScrollPositionLeft = 1 << 3, UICollectionViewScrollPositionCenteredHorizontally = 1 << 4, UICollectionViewScrollPositionRight = 1 << 5 };
變量
屬性名和變量名都采用小駝峰式命名規(guī)則
實(shí)例變量名以下劃線開(kāi)頭,局部變量不能以下劃線開(kāi)頭
-
禁止使用匈牙利標(biāo)記法或含糊不清的縮寫單詞來(lái)命名變量
for循環(huán)中的i允懂、j厕怜、k這種情況例外。
Objective-C中蕾总,變量名應(yīng)該盡量清楚的描述它的用途粥航。這樣可以使別人立即明白代碼的意思,不要擔(dān)心這樣會(huì)導(dǎo)致代碼過(guò)長(zhǎng)生百。
//以下這些都是錯(cuò)誤的命名規(guī)范 int w; int nerr; int nCompConns; tix = [[NSMutableArray alloc] init]; obj = [someObject object]; p = [network port]; //以下這些才是贊成的命名規(guī)范 int numErrors; int numCompletedConnections; tickets = [[NSMutableArray alloc] init]; userInfo = [someObject object]; port = [network port];
-
指針?lè)?hào) "*" 靠近變量名字递雀。(常量定義除外)
NSString *varName; //贊成的 NSString* varName; //不贊成的
-
使用property時(shí),優(yōu)先使用點(diǎn)語(yǔ)法
使用點(diǎn)語(yǔ)法會(huì)讓代碼簡(jiǎn)潔蚀浆。但對(duì)于其他情況缀程,都應(yīng)該使用方括號(hào)語(yǔ)法。
//贊成的 NSInteger arrayCount = [self.array count]; view.backgroundColor = [UIColor orangeColor]; [UIApplication sharedApplication].delegate; //不贊成的 NSInteger arrayCount = self.array.count; [view setBackgroundColor:[UIColor orangeColor]]; UIApplication.sharedApplication.delegate;
通知和異常
-
通知名字的命名規(guī)則:[相關(guān)聯(lián)的類名字] + [Did | Will] + [獨(dú)一無(wú)二的一段名稱] + Notification
如:UIApplicationDidBecomeActiveNotification
-
異常名字的命名規(guī)則:[前綴] + [獨(dú)一無(wú)二的一段名稱] + Exception
如:NSColorListIOException
布爾值
Objective-C的布爾值只使用
YES
和NO
true
和false
只能用于CoreFoundation蜡坊,C或C++的代碼中-
禁止將某個(gè)值或表達(dá)式的結(jié)果與
YES
進(jìn)行比較因?yàn)锽OOL被定義成signed char杠输。這意味著除了YES(1)和NO(0)以外,它還可能是其他值秕衙。
因此C或C++中的非0為真并不一定就是YES
//以下都是被禁止的
- (BOOL)isBold {
return [self fontTraits] & NSFontBoldTrait;
}
- (BOOL)isValid {
return [self stringValue];
}
if ([self isBold] == YES) {
//...
}
//以下才是贊成的方式
- (BOOL)isBold {
return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
- (BOOL)isValid {
return [self stringValue] != nil;
}
- (BOOL)isEnabled {
return [self isValid] && [self isBold];
}
if ([self isBold]) {
//...
}
-
雖然
nil
會(huì)被直接解釋成NO
蠢甲,但還是建議在條件判斷時(shí)保持與nil的比較,因?yàn)檫@樣代碼更直觀据忘。//比如鹦牛,更直觀的代碼 if (someObject != nil) { //... } //沒(méi)那么直觀的代碼 if (!someObject) { //... }
-
在C或C++代碼中,要注意NULL指針的檢測(cè)勇吊。
向一個(gè)nil的Objective-C對(duì)象發(fā)送消息不會(huì)導(dǎo)致崩潰曼追。但由于Objective-C運(yùn)行時(shí)不會(huì)處理給NULL指針的情況,所以為了避免崩潰汉规,需要自行處理對(duì)于C/C++的NULL指針的檢測(cè)礼殊。
-
如果某個(gè)
BOOL
類型的property的名字是一個(gè)形容詞驹吮,建議為getter方法加上一個(gè)"is"開(kāi)頭的別名。@property (assign, getter = isEditable) BOOL editable;
-
在方法實(shí)現(xiàn)中晶伦,如果有block參數(shù)碟狞,要注意檢測(cè)block參數(shù)為nil的情況。
- (void)exitWithCompletion:(void(^)(void))completion { // 錯(cuò)誤婚陪。 如果外部調(diào)用此方法時(shí)completion傳入nil族沃,此處會(huì)發(fā)生EXC_BAD_ACCESS completion(); // 正確。如果completion不存在則不調(diào)用泌参。 if (completion) { completion(); } }
條件語(yǔ)句
-
條件語(yǔ)句的語(yǔ)句體脆淹,即便只有一行,也不能省略花括弧
這樣可以減少失誤沽一。比如你在if語(yǔ)句體中增加第二行語(yǔ)句的時(shí)候盖溺,就可能會(huì)因?yàn)闆](méi)有花括號(hào)而導(dǎo)致新增的第二行語(yǔ)句沒(méi)有被包含在if語(yǔ)句體中。另外锯玛,這里還提到了其他的一些危險(xiǎn)情況咐柜。
//贊成的 if (error == nil) { return success; } //不贊成的 if (error == nil) return success; //或 if (error == nil) return success;
-
多層嵌套的條件語(yǔ)句,優(yōu)先考慮條件不成立可以立即跳出的情況
Objective-C的代碼普遍比較長(zhǎng)攘残,如果再加上多層嵌套的條件語(yǔ)句拙友,代碼縮進(jìn)會(huì)增多,代碼會(huì)變得更長(zhǎng)歼郭,會(huì)影響可讀性遗契。比如,下面這種情況病曾,換成優(yōu)先考慮可以跳出的情況牍蜂,可以有效的減少代碼縮進(jìn)長(zhǎng)度:
//一般流程
if (a) {
if (b) {
if (c) {
//do something
}
}
}
//優(yōu)先考慮可以跳出的流程
if (!a) {
return;
}
if (!b) {
return;
}
if (!c) {
return;
}
//do something
-
三目運(yùn)算只有在能增加代碼清晰度和整潔度的時(shí)候才推薦使用
三目運(yùn)算符(?:),如果不能增加代碼整潔度和清晰度泰涂,使用時(shí)就要謹(jǐn)慎鲫竞。特別是,嵌套使用多個(gè)三目運(yùn)算逼蒙,這種要盡量避免从绘。因?yàn)樗鼤?huì)使代碼更難閱讀。
另外是牢,三目運(yùn)算符中的條件判斷是一個(gè)語(yǔ)句僵井,最好用小括號(hào)括起來(lái)。如果直接是一個(gè)布爾值則無(wú)需括號(hào)驳棱。例如:
//贊成的 NSInteger value = 5; result = (value != 0) ? x : y; BOOL isHorizontal = YES; result = isHorizontal ? x : y; //不贊成的 result = a > b ? x = c > d ? c : d : y;
初始化方法
-
初始化方法的返回類型用
instancetype
關(guān)于instancetype的介紹參見(jiàn)NSHipster.com批什。
CGRect函數(shù)
-
訪問(wèn)CGRect中的x、y社搅、width或height元素時(shí)驻债,不直接訪問(wèn)而是使用CGGeometry相關(guān)函數(shù)
CGGeometry里面的函數(shù)乳规,會(huì)對(duì)CGRect參數(shù)進(jìn)行隱式的標(biāo)準(zhǔn)化處理,然后再計(jì)算結(jié)果合呐。因此驯妄,你應(yīng)該避免直接讀取或重寫CGRect數(shù)據(jù)結(jié)構(gòu)里面的值,而要使用這些函數(shù)來(lái)進(jìn)行相關(guān)操作合砂。
什么叫標(biāo)準(zhǔn)化處理,參見(jiàn)CGGeometry Reference的Overview章節(jié)源织。
//贊成的 CGRect frame = self.view.frame; CGFloat x = CGRectGetMinX(frame); CGFloat y = CGRectGetMinY(frame); CGFloat width = CGRectGetWidth(frame); CGFloat height = CGRectGetHeight(frame); CGRect frame = CGRectMake(0.0, 0.0, width, height); //不贊成的 CGRect frame = self.view.frame; CGFloat x = frame.origin.x; CGFloat y = frame.origin.y; CGFloat width = frame.size.width; CGFloat height = frame.size.height; CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };
Xcode工程結(jié)構(gòu)
-
實(shí)體文件應(yīng)該和XCode工程文件保持同步翩伪,防止出現(xiàn)文件不一致
任何手動(dòng)創(chuàng)建的XCode Group都應(yīng)該在文件系統(tǒng)有一個(gè)對(duì)應(yīng)的文件夾。代碼不僅要根據(jù)類型組織谈息,更要以更加清晰的特征來(lái)區(qū)分歸類缘屹。
-
建議:在可能的情況下,始終要勾選在Build設(shè)置選項(xiàng)中”Treat Warnings as Errors(將告警視為錯(cuò)誤)“選項(xiàng)侠仇。同時(shí)盡可能多的暴露更多的additional warnings(附加告警)轻姿。如果要忽略某類特定Warning(告警),請(qǐng)使用Clang's pragma feature逻炊。
此條不做強(qiáng)制要求互亮,但是"將警告視為錯(cuò)誤"是你應(yīng)當(dāng)要有的態(tài)度。
Just for fun
最后貼張圖娛樂(lè)一下余素,雖然說(shuō)Objective-C中長(zhǎng)名是美德豹休,但是什么東西還是要有個(gè)度。有人寫了個(gè)腳本統(tǒng)計(jì)Cocoa Framework中各種最長(zhǎng)的命名桨吊,結(jié)果發(fā)現(xiàn)低估了蘋果程序員的造句能力威根。Mac平臺(tái)最長(zhǎng)的常量名96個(gè)字符,最長(zhǎng)的方法名150個(gè)字符视乐,C函數(shù)名都能到68個(gè)字符洛搀! -_-# 泥煤,自從學(xué)會(huì)了Objective-C佑淀,媽媽再也不用擔(dān)心我的造句能力了留美。