使用ARC時(shí)的一些注意事項(xiàng)

1.ARC空聲明變量

使用ARC的另一個(gè)優(yōu)勢是所有未初始化的變量默認(rèn)都是“空值化”的。這意味著像下面這樣的聲明使用ARC編譯后指向的是空值(nil):

NSObject myObject1,myObjects2;

不過要注意的是,與其他高級編程語言不同,ARC不會(huì)自動(dòng)將標(biāo)量的值設(shè)置為零。
  這意味著以下幾行代碼聲明的變量其值并不等于零:

int a;
int b;


2.Objective-C命名約定

如果你在Person對象中寫了一個(gè)叫做newPersonName的方法,ARC會(huì)認(rèn)為該方法返回一個(gè)分配過的對象。使用ARC(或者不適用ARC)編譯過的調(diào)用代碼和方法newPersonName運(yùn)行時(shí)一切正常。但是如果這一方法所在的類沒有使用ARC編譯而調(diào)用方法使用了ARC編譯,程序就會(huì)奔潰。反過來,如果newPersonName方法是使用ARC編譯的而調(diào)用代碼沒有,就會(huì)出現(xiàn)內(nèi)存泄露。


3.覆蓋默認(rèn)行為

雖然從技術(shù)上說我們無法覆蓋LLVM的行為,但還是可以使用Clang源標(biāo)注NS_RETURNS_RETAINED和NS_RETURNS_NOT_RETAINED來更改方法。newPersonName方法可以像下面這樣標(biāo)注,以告訴ARC編譯器:盡管該方法名稱前面是new,返回的卻是未保留過的對象指針。

-(NSString *)newPersonName NS_RETURNS_NOT_RETAINED;

4.自由橋接

與Objective-C庫不同,我們在Objective-C中使用的標(biāo)準(zhǔn)C語言和Core Fundation類庫(CF 方法)不會(huì)遵循那些命名約定。這意味著ARC編譯器無法百分百地釋放不需要的內(nèi)存。在ARC出現(xiàn)之前,我么可以將CF對象強(qiáng)制轉(zhuǎn)變成NS對象,這稱為自由橋接(toll-free bridging)。也就是說,我們可以將CFString通過類型轉(zhuǎn)換變成NSString*類型。而有了ARC,我們便無法再這么做了,至少不指定一個(gè)所有權(quán)轉(zhuǎn)移修飾符時(shí)確實(shí)如此。

ARC允許使用一下這些所有權(quán)轉(zhuǎn)移修飾符:

__bridge
__bridge_retained
__bridge_transfer

1.__bridge
  它告訴ARC不要增加它的引用計(jì)數(shù)的值,也不要更改所有權(quán)。

2.__bridge_retained
  若想要轉(zhuǎn)換C指針類型并增加引用計(jì)數(shù)的值,我們可以使用第二個(gè)修飾符。當(dāng)要從Objective-C方法(它創(chuàng)建一個(gè)Core Fundation對象并在之后使用CFRelease方法將其釋放)返回一個(gè)保留過的指針時(shí),我們可以使用這個(gè)修飾符。如果Objective-C方法屬于NSRETURNS_RETAINDED系列,就要返回保留過的指針。

3.__bridge_transfer
  如果要將Core Fundation指針類型轉(zhuǎn)換成Objective-C指針并為引用計(jì)數(shù)加1,可以使用最后一個(gè)修飾符。若Core Fundation方法創(chuàng)建一個(gè)對象,并且想要靠ARC來管理對象的內(nèi)存,我們便可以使用這個(gè)修飾符。


5.忽略performSelector警告

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[uiViewController performSelector:finishMethod withObject:request];
#pragma clang diagnostic pop

6.block引起的循環(huán)保留

使用__block避免循環(huán)保留(無ARC)

__block id safeSelf = self;
self.myBlock = ^(NSString* returnedString){
    safeSelf.labelControl.text = returnedString;
};

ARC會(huì)改變__block的語義,因此不應(yīng)該使用它。在ARC中,__block引用會(huì)被保留而不是被復(fù)制,這意味著在ARC環(huán)境中前面的代碼仍然會(huì)引發(fā)循環(huán)保留。正確地方法是使用__weak或(__unsafe_unretained)引用,如:

使用__weak避免循環(huán)保留(有ARC)

__weak typeof(self) safeSelf = self;//IOS 5+
//__unsafe_unretained typeof(self) safeSelf = self;//IOS 4+
self.myBlock = ^(NSString* returnedString){
    safeSelf.labelControl.text = returnedString;
};

微博鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容