@(〓〓 iOS-Objective-C精選)[Objective-C 文章精選]
- 作者: Liwx
- 郵箱: 1032282633@qq.com
目錄
- 01.優(yōu)秀的Objective-C編碼風(fēng)格指南
- 參考文檔
- 目錄
- 代碼結(jié)構(gòu)
- 代碼格式化
- 注釋
- 命名規(guī)范
- 類名/類別名/協(xié)議
- 方法
- 函數(shù)
- 常量
- 變量
- 通知和異常
- 布爾值
- 條件語句
- 初始化方法
- 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)度最多不超過100個(gè)字符
為了防止代碼過長(zhǎng),也為了兼顧Macbook上的排版效果,將每行長(zhǎng)度限制成100個(gè)字符。
勾選XCode->Preferences->Text Editing->Editing,并將長(zhǎng)度設(shè)置成100個(gè)字符來打開行寬指示。
ps. Google倡導(dǎo)的每行80個(gè)字符有點(diǎn)少,會(huì)帶來更頻繁的換行,因此增加到100個(gè)字符。
-
建議:嘗試將單個(gè)函數(shù)或方法的實(shí)現(xiàn)代碼控制在30行內(nèi)
如果某個(gè)函數(shù)或方法的實(shí)現(xiàn)代碼過長(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)接近或超過800行時(shí),就應(yīng)當(dāng)開始考慮分割實(shí)現(xiàn)文件了。
最好不要出現(xiàn)代碼超過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,開啟行號(hào)提示。
-
實(shí)現(xiàn)文件中,函數(shù)實(shí)現(xiàn)或方法實(shí)現(xiàn)之間必須至少有一行空行
沒有空行,代碼過長(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ū)隔開來,方便閱讀,也方便查找是否忘記了對(duì)super的調(diào)用。- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; //空一行,將super方法的調(diào)用和重載代碼區(qū)隔開來。 [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)后面緊接著的代碼塊超過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與上一條分支語句的右括號(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)用中部分的代碼過長(zhǎng),造成內(nèi)嵌的block代碼縮進(jìn)過長(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ī)范
無論什么情況下,都要盡量堅(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è)類庫中,使用了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ù)過多超過一行時(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)該盡量讀起來像一句話。具體參見蘋果的方法名命名規(guī)范
如:convertPoint:fromRect: 或者 replaceCharactersInRange:withString:
-
當(dāng)各個(gè)參數(shù)是接收者的某個(gè)屬性時(shí),方法名中不要用"and"來連接
//贊成的 - (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; //不贊成的 - (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
-
如果方法名描述了兩種不同的動(dòng)作,要使用"and"來連接
- (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; //禁止
-
類私有方法以下劃線開頭
如:
- (void)_startDownloadFiles;
Objective-C里面沒有真正嚴(yán)格意義上私有方法。這里所說的"私有方法"指那些不需要公開的、只會(huì)在實(shí)現(xiàn)文件中使用的方法。
這樣做的好處是,可以直觀的快速區(qū)別實(shí)現(xiàn)文件中的私有方法和公有方法。
這樣做會(huì)很便于重構(gòu)。如果某個(gè)方法廢棄了,需要移除的時(shí)候,發(fā)現(xiàn)它是以下劃線開頭的,那么就可以確定這個(gè)方法是私有的,只會(huì)在這個(gè)實(shí)現(xiàn)文件中被用到。那么直接在該實(shí)現(xiàn)文件搜索這個(gè)方法的名字,然后清理掉搜索到的地方就可以了。不必再在整個(gè)項(xiàng)目中查找是否沒有清理干凈。
根據(jù)蘋果的建議,這種做法可能覆蓋掉父類的私有方法。
但是目前還沒有遇到過這種情況,而且我們認(rèn)為此條約定帶來的好處遠(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語法
//例如: 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ò)誤問題。
比如:
static CGFloat const RWImageThumbnailHeight = 50.0;
-
常量名以小寫k開頭,采用首字母大寫的方式來分割單詞
//例如: const int kNumberOfFiles = 12; NSString *const kUserKey = @"kUserKey"; enum DisplayTinge { kDisplayTingeGreen = 1, kDisplayTingeBlue = 2 };
-
和特定類型相關(guān)的枚舉常量使用類名作為前綴,而不用小寫k開頭。
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í)例變量名以下劃線開頭,局部變量不能以下劃線開頭
-
禁止使用匈牙利標(biāo)記法或含糊不清的縮寫單詞來命名變量
for循環(huán)中的i、j、k這種情況例外。
Objective-C中,變量名應(yīng)該盡量清楚的描述它的用途。這樣可以使別人立即明白代碼的意思,不要擔(dān)心這樣會(huì)導(dǎo)致代碼過長(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];
-
指針符號(hào) "*" 靠近變量名字。(常量定義除外)
NSString *varName; //贊成的 NSString* varName; //不贊成的
-
使用property時(shí),優(yōu)先使用點(diǎn)語法
使用點(diǎn)語法會(huì)讓代碼簡(jiǎn)潔。但對(duì)于其他情況,都應(yīng)該使用方括號(hào)語法。
//贊成的 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ú)一無二的一段名稱] + Notification
如:UIApplicationDidBecomeActiveNotification
-
異常名字的命名規(guī)則:[前綴] + [獨(dú)一無二的一段名稱] + 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) { //... } //沒那么直觀的代碼 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"開頭的別名。@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(); } }
條件語句
-
條件語句的語句體,即便只有一行,也不能省略花括弧
這樣可以減少失誤。比如你在if語句體中增加第二行語句的時(shí)候,就可能會(huì)因?yàn)闆]有花括號(hào)而導(dǎo)致新增的第二行語句沒有被包含在if語句體中。另外,這里還提到了其他的一些危險(xiǎn)情況。
//贊成的 if (error == nil) { return success; } //不贊成的 if (error == nil) return success; //或 if (error == nil) return success;
-
多層嵌套的條件語句,優(yōu)先考慮條件不成立可以立即跳出的情況
Objective-C的代碼普遍比較長(zhǎng),如果再加上多層嵌套的條件語句,代碼縮進(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è)語句,最好用小括號(hào)括起來。如果直接是一個(gè)布爾值則無需括號(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的介紹參見NSHipster.com。
CGRect函數(shù)
-
訪問CGRect中的x、y、width或height元素時(shí),不直接訪問而是使用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ù)來進(jìn)行相關(guān)操作。
什么叫標(biāo)準(zhǔ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ù)類型組織,更要以更加清晰的特征來區(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
最后貼張圖娛樂一下,雖然說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)心我的造句能力了。