命名規(guī)范
1.【強(qiáng)制】 代碼中的命名均不能以下劃線或美元符號(hào)開始,也不能以下劃線或美元符號(hào)結(jié)束。
反例: _name / __name / $Object / name_ / name$ / Object$
2.【強(qiáng)制】 代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。
說明:正確的英文拼寫和語法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式 也要避免采用。
反例:DaZhePromotion [打折] / getPingfenByName() [評(píng)分] / int 某變量 = 3
正例:alibaba / taobao / youku / hangzhou 等國際通用的名稱,可視同英文。
3.【強(qiáng)制】類名使用 UpperCamelCase 風(fēng)格,必須遵從駝峰形式,但領(lǐng)域模型相關(guān)的命名除外,比如 UserDAO
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
4.【強(qiáng)制】方法名、參數(shù)名、成員變量、局部變量都統(tǒng)一使用 lowerCamelCase 風(fēng)格,必須遵從 駝峰形式。
正例:localValue / getHttpMessage / inputUserId
5.【強(qiáng)制】常量命名全部大寫,單詞間用下劃線隔開,力求語義表達(dá)完整清楚,不要嫌名字長。
正例:MAX_STOCK_COUNT
反例:MAX_COUNT
6.【強(qiáng)制】異常類命名使用 Exception 結(jié)尾;測試類命名以它要測試的類的名稱開始,以 Test 結(jié)尾。
7.【強(qiáng)制】杜絕完全不規(guī)范的縮寫,避免望文不知義。
8.【強(qiáng)制】文件名和類名同名。
9.【推薦】如果使用到了設(shè)計(jì)模式,建議在類名中體現(xiàn)出具體模式。
說明:將設(shè)計(jì)模式體現(xiàn)在名字中,有利于閱讀者快速理解架構(gòu)設(shè)計(jì)思想。
10.【推薦】類名應(yīng)加上三個(gè)大寫字母作為前綴(兩個(gè)字母的為 Apple 的類保留)。
11.【強(qiáng)制】特殊類的命名,如果是視圖控制器的子類應(yīng)添加后綴“ViewController”或者“Controller”,如果是視圖的子類應(yīng)添加后綴“View”,如果是按鈕的子類應(yīng)添加后綴“Button”。
12.【強(qiáng)制】分類 Category 命名,與類命名相同,此外需添加要擴(kuò)展的類名和“+”
13.【強(qiáng)制】協(xié)議(委托)命名,與類命名相同,此外需添加“Delegate”后綴
14.【推薦】方法返回值為Boolean 類型,應(yīng)加 is 前綴。如果某方法返回非屬性的 Boolean 值,那么應(yīng)該根據(jù)其功能,選用 has 或 is 當(dāng)前綴。
- (BOOL)isEqualToString:(NSString *)aString;
- (BOOL)hasPrefix:(NSString *)aString;
15.【推薦】方法名不要使用 new 作為前綴
16.【推薦】不要使用 and 來連接用屬性作參數(shù)的關(guān)鍵字
17.【推薦】方法連接多個(gè)參數(shù)命名時(shí),適當(dāng)使用合適的介詞。比如 in for at by of with
//清晰
insertObject:atIndex:
//不清晰,insert的對(duì)象類型和at的位置屬性沒有說明
insert:at:
//清晰
removeObjectAtIndex:
//不清晰,remove的對(duì)象類型沒有說明,參數(shù)的作用沒有說明
remove:
18.【推薦】定義成員變量,添加下劃線前綴。但不推薦使用成員變量,直接使用屬性。
19.【強(qiáng)制】資源圖片命名,圖片應(yīng)該與類文件一樣,按模塊分組放置,縮略前綴可用如下例子
icon btn bg line logo pic img
常量定義
1.【強(qiáng)制】不允許出現(xiàn)任何魔法值(即未經(jīng)定義的常量)直接出現(xiàn)在代碼中。
2.【推薦】不要使用一個(gè)常量類維護(hù)所有常量,應(yīng)該按常量功能進(jìn)行歸類,分開維護(hù)。
如:緩存相關(guān)的常量放在類:CacheConsts下;系統(tǒng)配置相關(guān)的常量放在類:ConfigConsts下。
說明:大而全的常量類,非得使用查找功能才能定位到修改的常量,不利于理解和維護(hù)。
3.【強(qiáng)制】常量使用小寫k開頭的駝峰法。
static const NSTimeInterval kAnimationDuration = 0.3;
4.【強(qiáng)制】若常量作用域超出編譯單元,在類外可見時(shí),
.h
extern NSString *const EOCStringConstant;
.m
NSString *const EOCStringConstant = @"aaa";
5.【強(qiáng)制】全局常量(通知或者關(guān)鍵字等)盡量用const來定義,而不是宏。因?yàn)槿绻褂煤甓x, 宏可能被重定義,引用不同的文件可能會(huì)導(dǎo)致宏的不同。
格式規(guī)范
1.【強(qiáng)制】大括號(hào)的使用約定。如果是大括號(hào)內(nèi)為空,則簡潔地寫成{}即可,不需要換行;如果 是非空代碼塊則:
- 左大括號(hào)前不換行。
- 左大括號(hào)后換行。
- 右大括號(hào)前換行。
- 右大括號(hào)后還有else等代碼則不換行;表示終止右大括號(hào)后必須換行。
2.【強(qiáng)制】 左括號(hào)和后一個(gè)字符之間不出現(xiàn)空格;同樣,右括號(hào)和前一個(gè)字符之間也不出現(xiàn)空格。
3.【強(qiáng)制】if/for/while/switch/do 等保留字與左右括號(hào)之間都必須加空格。
4.【強(qiáng)制】任何運(yùn)算符左右必須加一個(gè)空格。
說明:運(yùn)算符包括賦值運(yùn)算符=、邏輯運(yùn)算符&&、加減乘除符號(hào)、三目運(yùn)算符等。
5.【強(qiáng)制】縮進(jìn)采用 4 個(gè)空格,禁止使用 tab 字符。
- (void)method {
// 縮進(jìn) 4 個(gè)空格
NSString *say = @"hello";
// 運(yùn)算符的左右必須有一個(gè)空格
NSInteger flag = 0;
// 關(guān)鍵詞 if 與括號(hào)之間必須有一個(gè)空格,括號(hào)內(nèi)的 f 與左括號(hào),0 與右括號(hào)不需要空格
if (flag == 0) {
NSLog(@"%@", say);
}
// 左大括號(hào)前不加空格且不換行,左大括號(hào)后換行
if (flag == 1) {
NSLog(@"world");
// 右大括號(hào)前換行,右大括號(hào)后有 else,不用換行
} else {
NSLog(@"ok");
// 在右大括號(hào)后直接結(jié)束,則必須換行
}
}
6.【強(qiáng)制】單行字符數(shù)限制不超過 120 個(gè),超出需要換行,按照:來對(duì)齊分行顯示
-(id)initWithModel:(IPCModle)model
ConnectType:(IPCConnectType)connectType
Resolution:(IPCResolution)resolution
AuthName:(NSString *)authName
Password:(NSString *)password
MAC:(NSString *)mac
AzIp:(NSString *)az_ip
AzDns:(NSString *)az_dns
Token:(NSString *)token
Email:(NSString *)email
Delegate:(id<IPCConnectHandlerDelegate>)delegate;
在分行時(shí),如果第一段名稱過短,后續(xù)名稱可以以Tab的長度(4個(gè)空格)為單位進(jìn)行縮進(jìn):
- (void)short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval
error:(NSError **)theError {
...
}
函數(shù)的調(diào)用同理。
//寫在一行
[myObject doFooWith:arg1 name:arg2 error:arg3];
//分行寫,按照':'對(duì)齊
[myObject doFooWith:arg1
name:arg2
error:arg3];
//第一段名稱過短的話后續(xù)可以進(jìn)行縮進(jìn)
[myObj short:arg1
longKeyword:arg2
evenLongerKeyword:arg3
error:arg4];
7.【強(qiáng)制】多個(gè)參數(shù)逗號(hào)后邊必須加空格。
正例:
NSLog(@"%@-%@-%@-%@", a, b, c, d);
8.【推薦】沒有必要增加若干空格來使某一行的字符與上一行的相應(yīng)字符對(duì)齊。
說明:在變量比較多的 情況下,是一種累贅的事情。
@interface HOECoupon : NSObject
@property (nonatomic, assign) NSInteger couponId;
@property (nonatomic, copy) NSString *startTime;
@property (nonatomic, copy) NSString *endTime;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subTitle;
@property (nonatomic, assign) NSInteger state;
@property (nonatomic, assign) NSInteger canUse;
@property (nonatomic, assign) CGFloat price;
@property (nonatomic, copy) NSString *stateDesc;
@property (nonatomic, copy) NSString *reason;
@end
9.【推薦】方法體內(nèi)的執(zhí)行語句組、變量的定義語句組、不同的業(yè)務(wù)邏輯之間或者不同的語義之間插入一個(gè)空行。相同業(yè)務(wù)邏輯和語義之間不需要插入空行。
說明:沒有必要插入多行空格進(jìn)行隔開。
10.【推薦】.m實(shí)現(xiàn)類中推薦的代碼結(jié)構(gòu)如下
#pragma mark - lifecycle
- (void)dealloc
- (void)viewDidLoad
- (void)viewWillAppear:(BOOL)animated
...
#pragma mark - UITableViewDataSource & UITableViewDelegate
...
#pragma mark - Event handlers
- (void)didTapLikeButton:
...
#pragma mark - public methods
...
#pragma mark - private methods
- (void)setupTableView
- (void)setupNotification
...
#pragma mark - getters & setters
...
11.【推薦】頭文件引用的順序
// controllers
#import "OrcaAddFriendFromContactsViewController.h"
...
// views
...
// consts
...
// utils
...
// others
12.【推薦】方法的格式,在-和(void)之間應(yīng)該有一個(gè)空格
- (void)writeVideoFrameWithData:(NSData *)frameData timeStamp:(int)timeStamp {
...
}
面向?qū)ο笠?guī)范
1.【強(qiáng)制】避免通過一個(gè)類的對(duì)象引用訪問此類的靜態(tài)變量或靜態(tài)方法,無謂增加編譯器解析成本,直接用類名來訪問即可。
2.【強(qiáng)制】不能使用過時(shí)的類或方法。
3.【強(qiáng)制】推薦使用 NS_ENUM ,而不是 enum
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
UIViewAnimationTransitionNone,
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown,
};
4.【推薦】盡量使用字面量來初始化
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
5.【推薦】建議定義屬性的時(shí)候把所有的參數(shù)寫全, 尤其是如果想定義成只讀的(防止外面修改)那一定要加上readonly, 這也是代碼安全性的一個(gè)習(xí)慣。
@property (nonatomic, readwrite, copy) NSString *name;
6.【強(qiáng)制】方法參數(shù)過多,需要進(jìn)行重構(gòu)
正例:
- (void)registerUser(User *user) {
// to do...
}
反例:
- (void)registerUserName:(NSString *)userName
password:(NSString *)password
email:(NSString *)email {
// to do...
}
7.【強(qiáng)制】不推薦使用成員變量,直接使用屬性。
8.【推薦】setter 方法中,參數(shù)名稱與類成員變量名稱一致,self.成員名 = 參數(shù)名。在getter/setter 方法中,盡量不要增加業(yè)務(wù)邏輯,增加排查問題的難度。
9.【推薦】對(duì)于簡單對(duì)象,推薦在getter方法中延遲加載屬性,如果創(chuàng)建復(fù)雜對(duì)象,那么對(duì)象的創(chuàng)建最好放到類的初始化時(shí),而不是延遲加載。
10.【推薦】協(xié)議,在書寫協(xié)議的時(shí)候注意用<>括起來的協(xié)議和類型名之間是沒有空格的
@interface MyProtocoledClass : NSObject<NSWindowDelegate> {
}
- (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
@end
11.【推薦】閉包Block規(guī)則
- 較短的block可以寫在一行內(nèi)。
- 如果分行顯示的話,block的右括號(hào)}應(yīng)該和調(diào)用block那行代碼的第一個(gè)非空字符對(duì)齊。
- block內(nèi)的代碼采用4個(gè)空格的縮進(jìn)。
- 如果block過于龐大,應(yīng)該單獨(dú)聲明成一個(gè)變量來使用。
- ^ 和(之間,^ 和{之間都沒有空格,參數(shù)列表的右括號(hào))和{之間有一個(gè)空格。
//較短的block寫在一行內(nèi)
[operation setCompletionBlock:^{ [self onOperationDone]; }];
//分行書寫的block,內(nèi)部使用4空格縮進(jìn)
[operation setCompletionBlock:^{
[self.delegate newDataAvailable];
}];
//使用C語言API調(diào)用的block遵循同樣的書寫規(guī)則
dispatch_async(_fileIOQueue, ^{
NSString* path = [self sessionFilePath];
if (path) {
// ...
}
});
//較長的block關(guān)鍵字可以縮進(jìn)后在新行書寫,注意block的右括號(hào)'}'和調(diào)用block那行代碼的第一個(gè)非空字符對(duì)齊
[[SessionService sharedService]
loadWindowWithCompletionBlock:^(SessionWindow *window) {
if (window) {
[self windowDidLoad:window];
} else {
[self errorLoadingWindow];
}
}];
//較長的block參數(shù)列表同樣可以縮進(jìn)后在新行書寫
[[SessionService sharedService]
loadWindowWithCompletionBlock:
^(SessionWindow *window) {
if (window) {
[self windowDidLoad:window];
} else {
[self errorLoadingWindow];
}
}];
//龐大的block應(yīng)該單獨(dú)定義成變量使用
void (^largeBlock)(void) = ^{
// ...
};
[_operationQueue addOperationWithBlock:largeBlock];
//在一個(gè)調(diào)用中使用多個(gè)block,注意到他們不是像函數(shù)那樣通過':'對(duì)齊的,而是同時(shí)進(jìn)行了4個(gè)空格的縮進(jìn)
[myObject doSomethingWith:arg1
firstBlock:^(Foo *a) {
// ...
}
secondBlock:^(Bar *b) {
// ...
}];
12.【推薦】不要用點(diǎn)分語法來調(diào)用方法,只用來訪問屬性。這樣是為了防止代碼可讀性問題。
//正確,使用點(diǎn)分語法訪問屬性
NSString *oldName = myObject.name;
myObject.name = @"Alice";
//錯(cuò)誤,不要用點(diǎn)分語法調(diào)用方法
NSArray *array = [NSArray arrayWithObject:@"hello"];
NSUInteger numberOfItems = array.count;
13.BOOL 的使用
BOOL在Objective-C中被定義為signed char類型,這意味著一個(gè)BOOL類型的變量不僅僅可以表示YES(1)和NO(0)兩個(gè)值,所以永遠(yuǎn)不要將BOOL類型變量直接和YES比較:
//錯(cuò)誤,無法確定|great|的值是否是YES(1),不要將BOOL值直接與YES比較
BOOL great = [foo isGreat];
if (great == YES)
// ...be great!
//正確
BOOL great = [foo isGreat];
if (great)
// ...be great!
同樣的,也不要將其它類型的值作為BOOL來返回,這種情況下,BOOL變量只會(huì)取值的最后一個(gè)字節(jié)來賦值,這樣很可能會(huì)取到0(NO)。但是,一些邏輯操作符比如&&,||,!的返回是可以直接賦給BOOL的:
//錯(cuò)誤,不要將其它類型轉(zhuǎn)化為BOOL返回
- (BOOL)isBold {
return [self fontTraits] & NSFontBoldTrait;
}
- (BOOL)isValid {
return [self stringValue];
}
//正確
- (BOOL)isBold {
return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
//正確,邏輯操作符可以直接轉(zhuǎn)化為BOOL
- (BOOL)isValid {
return [self stringValue] != nil;
}
- (BOOL)isEnabled {
return [self isValid] && [self isBold];
}
14.不要使用new方法
盡管很多時(shí)候能用new代替alloc init方法,但這可能會(huì)導(dǎo)致調(diào)試內(nèi)存時(shí)出現(xiàn)不可預(yù)料的問題。Cocoa的規(guī)范就是使用alloc init方法,使用new會(huì)讓一些讀者困惑。
15.Public API要盡量簡潔
共有接口要設(shè)計(jì)的簡潔,滿足核心的功能需求就可以了。不要設(shè)計(jì)很少會(huì)被用到,但是參數(shù)極其復(fù)雜的API。如果要定義復(fù)雜的方法,使用類別或者類擴(kuò)展。
集合處理
1.【強(qiáng)制】對(duì)于可變集合類型作為屬性時(shí)使用strong,不可變集合類型使用copy
2.【強(qiáng)制】盡量不要暴露mutable類型的對(duì)象在public interface, 建議在.h定義一個(gè)Inmutable類型的屬性, 然后在.m的get函數(shù)里面返回一個(gè)內(nèi)部定義的mutable變量。保證類的不可變性。
3.使用NSNumber的語法糖
使用帶有@符號(hào)的語法糖來生成NSNumber對(duì)象能使代碼更簡潔:
NSNumber *fortyTwo = @42;
NSNumber *piOverTwo = @(M_PI / 2);
enum {
kMyEnum = 2;
};
NSNumber *myEnum = @(kMyEnum);
4.保證NSString在賦值時(shí)被復(fù)制
NSString非常常用,在它被傳遞或者賦值時(shí)應(yīng)當(dāng)保證是以復(fù)制(copy)的方式進(jìn)行的,這樣可以防止在不知情的情況下String的值被其它對(duì)象修改。
- (void)setFoo:(NSString *)aFoo {
_foo = [aFoo copy];
}
5.按照定義的順序釋放資源
在類或者Controller的生命周期結(jié)束時(shí),往往需要做一些掃尾工作,比如釋放資源,停止線程等,這些掃尾工作的釋放順序應(yīng)當(dāng)與它們的初始化或者定義的順序保持一致。這樣做是為了方便調(diào)試時(shí)尋找錯(cuò)誤,也能防止遺漏。
并發(fā)處理
1.【強(qiáng)制】獲取單例對(duì)象需要保證線程安全,其中的方法也要保證線程安全。
2.定義一個(gè)屬性時(shí),編譯器會(huì)自動(dòng)生成線程安全的存取方法(Atomic),但這樣會(huì)大大降低性能,特別是對(duì)于那些需要頻繁存取的屬性來說,是極大的浪費(fèi)。所以如果定義的屬性不需要線程保護(hù),記得手動(dòng)添加屬性關(guān)鍵字nonatomic來取消編譯器的優(yōu)化。
控制語句
1.【強(qiáng)制】在一個(gè) switch 塊內(nèi),每個(gè) case 要么通過 break/return 等來終止,要么注釋說明程 序?qū)⒗^續(xù)執(zhí)行到哪一個(gè) case 為止;在一個(gè) switch 塊內(nèi),都必須包含一個(gè) default 語句并且 放在最后,即使它什么代碼也沒有。
2.【強(qiáng)制】在 if/else/for/while/do 語句中必須使用大括號(hào),即使只有一行代碼,避免使用 下面的形式:if (condition) statements;
3.【推薦】推薦盡量少用 else, if-else 的方式可以改寫成:
if (condition) {
...
return obj;
}
// 接著寫 else 的業(yè)務(wù)邏輯代碼;
4.【強(qiáng)制】請(qǐng)勿超過 3 層,超過請(qǐng)使用狀態(tài)設(shè)計(jì)模式。
正例:邏輯上超過 3 層的 if-else 代碼可以使用衛(wèi)語句,或者狀態(tài)模式來實(shí)現(xiàn)。
5.【強(qiáng)制】三目運(yùn)算符的使用
正例:
result = object ? : [self createObject];
反例:
result = object ? object : [self createObject];
6.【強(qiáng)制】對(duì)于復(fù)雜的條件判斷,要提取一個(gè)變量出來
正例:
([self canDeleteJob:job]) { ... }
- (BOOL)canDeleteJob:(Job *)job {
BOOL invalidJobState = job.JobState == JobState.New
|| job.JobState == JobState.Submitted
|| job.JobState == JobState.Expired;
BOOL invalidJob = job.JobTitle && job.JobTitle.length;
return invalidJobState || invalidJob;
}
反例:
if (job.JobState == JobState.New
|| job.JobState == JobState.Submitted
|| job.JobState == JobState.Expired
|| (job.JobTitle && job.JobTitle.length))
{
//....
}
7.【強(qiáng)制】對(duì)于嵌套判斷,一旦發(fā)現(xiàn)某個(gè)條件不符合,立即返回,條理更清晰
正例:
if (!user.UserName) return NO;
if (!user.Password) return NO;
if (!user.Email) return NO;
return YES;
反例:
Not preferred:
BOOL isValid = NO;
if (user.UserName)
{
if (user.Password)
{
if (user.Email) isValid = YES;
}
}
return isValid;
注釋規(guī)范
1.【強(qiáng)制】類、類屬性、類方法的注釋必須使用文檔注釋,不得使用 //xxx 方式。
2.【強(qiáng)制】所有的類都必須添加創(chuàng)建者信息。
3.【強(qiáng)制】方法內(nèi)部單行注釋,在被注釋語句上方另起一行,使用//注釋。方法內(nèi)部多行注釋
使用/* */注釋,注意與代碼對(duì)齊。
4.【強(qiáng)制】所有的枚舉類型字段必須要有注釋,說明每個(gè)數(shù)據(jù)項(xiàng)的用途。
5.【推薦】代碼修改的同時(shí),注釋也要進(jìn)行相應(yīng)的修改,尤其是參數(shù)、返回值、異常、核心邏輯 等的修改。
6.【參考】注釋掉的代碼盡量要配合說明,而不是簡單的注釋掉。
說明:代碼被注釋掉有兩種可能性:1)后續(xù)會(huì)恢復(fù)此段代碼邏輯。2)永久不用。前者如果沒 有備注信息,難以知曉注釋動(dòng)機(jī)。后者建議直接刪掉(代碼倉庫保存了歷史代碼)。
7.【參考】好的命名、代碼結(jié)構(gòu)是自解釋的,注釋力求精簡準(zhǔn)確、表達(dá)到位。避免出現(xiàn)注釋的一個(gè)極端:過多過濫的注釋,代碼的邏輯一旦修改,修改注釋是相當(dāng)大的負(fù)擔(dān)。
8.【參考】特殊注釋標(biāo)記,請(qǐng)注明標(biāo)記人與標(biāo)記時(shí)間。注意及時(shí)處理這些標(biāo)記,通過標(biāo)記掃描,經(jīng)常清理此類標(biāo)記。線上故障有時(shí)候就是來源于這些標(biāo)記處的代碼。
待辦事宜(TODO):( 標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間]) 表示需要實(shí)現(xiàn),但目前還未實(shí)現(xiàn)的功能。
錯(cuò)誤,不能工作(FIXME):(標(biāo)記人,標(biāo)記時(shí)間,[預(yù)計(jì)處理時(shí)間])
在注釋中用 FIXME 標(biāo)記某代碼是錯(cuò)誤的,而且不能工作,需要及時(shí)糾正的情況。
其他
1.【強(qiáng)制】避免 block 的循環(huán)引用
__weak typeof(self) weakSelf = self;
myObj.myBlock = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomething]; // strongSelf != nil
// preemption, strongSelf still not nil
[strongSelf doSomethingElse]; // strongSelf != nil
}
else {
// Probably nothing...
return;
}
};
2.Delegate要使用弱引用
一個(gè)類的Delegate對(duì)象通常還引用著類本身,這樣很容易造成引用循環(huán)的問題,所以類的Delegate屬性要設(shè)置為弱引用。
/** delegate */
@property (nonatomic, weak) id <IPCConnectHandlerDelegate> delegate;
3.nil檢查
因?yàn)樵贠bjective-C中向nil對(duì)象發(fā)送命令是不會(huì)拋出異?;蛘邔?dǎo)致崩潰的,只是完全的“什么都不干”,所以,只在程序中使用nil來做邏輯上的檢查。
另外,不要使用諸如nil == Object或者Object == nil的形式來判斷。
//正確,直接判斷
if (!objc) {
...
}
//錯(cuò)誤,不要使用nil == Object的形式
if (nil == objc) {
...
}