前言
自動(dòng)引用計(jì)數(shù) 是指內(nèi)存管理中對(duì)引用采取自動(dòng)計(jì)數(shù)的技術(shù)。
OC中ARC
模式是讓編譯器來(lái)替我們實(shí)現(xiàn)內(nèi)存管理,我們無(wú)需再像在MRC
模式下需要手動(dòng)鍵入retain
、release
來(lái)進(jìn)行內(nèi)存管理,不但降低了程序的出錯(cuò)概率也減少了程序的書(shū)寫(xiě)工作量。這里要提一下的是,擁有ARC
這樣強(qiáng)大內(nèi)存管理模式主要依賴于3.0
及以上版本的LLVM
編譯器。
內(nèi)存管理
OC內(nèi)存管理的核心就是引用計(jì)數(shù)。我們以遛狗的場(chǎng)景為例來(lái)解釋引用計(jì)數(shù)機(jī)制:
當(dāng)人物A要出門(mén)遛狗的時(shí)候,A會(huì)在狗的脖子上栓一條鏈子牽著它。然后人物B也想同時(shí)溜這條狗(當(dāng)然在現(xiàn)實(shí)中這種情況比較奇葩了,我們先不考慮這個(gè)),B會(huì)在狗的脖子上再拴上一條鏈子,這時(shí)兩個(gè)人都對(duì)這條狗持有。當(dāng)A不想溜了就會(huì)解開(kāi)鏈子,此時(shí)狗的脖子上只有B持有的一條鏈子。當(dāng)B也不想溜了,B也解開(kāi)了狗脖子上的鏈子。此時(shí)狗的脖子上沒(méi)有鏈子的束縛,狗就逃掉了。
上邊情景中狗就是對(duì)象,人物在狗的脖子上拴上鏈子就是引用,解開(kāi)狗脖子上的鏈子就是釋放,狗脖子上鏈子數(shù)就是引用計(jì)數(shù),當(dāng)狗脖子上鏈子數(shù)為0狗會(huì)逃走,也就是當(dāng)對(duì)象引用計(jì)數(shù)為0對(duì)象就被完全釋放。
下面用一個(gè)圖示解釋一下:
對(duì)象的引用計(jì)數(shù)我們可以通過(guò)
[object retainCount];
獲取。
圖示中有四個(gè)動(dòng)詞:生成、持有、釋放、廢棄,這四個(gè)詞分別對(duì)應(yīng)OC中的哪些方法以及含義呢?
- 生成并持有:
alloc
/new
/copy
/mutableCopy
等
自己(這里的自己應(yīng)該理解為生成對(duì)象的‘當(dāng)前環(huán)境’)生成的對(duì)象,并持有它。 - 持有:
retain
非自己生成的對(duì)象,自己去持有它。 - 釋放:
release
不再需要自己持有的對(duì)象,釋放它。 - 廢棄:
dealloc
對(duì)象不再被需要,被銷毀。
其實(shí)這些內(nèi)存管理的方法并不是OC語(yǔ)言本身提供的,而是NSObject
類本身肩負(fù)了內(nèi)存管理的職責(zé),alloc
是NSObject
類的類方法,retain
、release
、dealloc
是NSObject
類的實(shí)例方法。
生成并持有
除了使用alloc
、new
、copy
、mutableCopy
方法外:
使用alloc
、new
、copy
、mutableCopy
開(kāi)頭的方法同樣意味著自己生成并持有,如:
allocOneObject
newThatObject
copyThis
mutableCopyYourObject
...
例如:
- (id)allocObject{
id object = [[NSObject alloc] init];
return object;
}
命名規(guī)則必須遵循駝峰寫(xiě)法,以下命名的方法則不屬于自己生成并持有的范疇
alloconeobject
newthatobject
...
copy
、mutableCopy
方法是分別依賴于NSCopying
、NSMutableCopy
協(xié)議,由各類實(shí)現(xiàn)的copyWithZone:
、mutableCopyWithZone:
方法生成并持有的對(duì)象的副本。這些方法雖然生成的是副本,但依然是自己生成并持有。
持有
除了以上的方法外,我們來(lái)看看NSMutableArray
的array
方法
// 取得非自己生成的對(duì)象
id object = [NSMutableArray array];
// 通過(guò)retain函數(shù),實(shí)現(xiàn)自己持有
[object retain];
釋放
當(dāng)我們不在需要持有對(duì)象的時(shí)候,我們就要釋放對(duì)對(duì)象的持有,那就要用到release
方法
id object = [[NSMutableArray alloc] init];
// 釋放持有
[object release];
id object = [NSMutableArray array];
[object retain];
// 釋放持有
[object release];
都可以使用release函數(shù)進(jìn)行釋放
注意:我們是無(wú)法釋放非自己持有的對(duì)象的,比如:
id object = [[NSObject alloc] init];
// 釋放對(duì)象 自己不再持有
[object release];
// 當(dāng)再次釋放自己已經(jīng)不再持有的對(duì)象就會(huì)報(bào)錯(cuò)
[object release]; // 所以這一句代碼是錯(cuò)誤的
ARC規(guī)則
上面介紹的大多數(shù)方法都是MRC
模式下我們手動(dòng)管理內(nèi)存的操作方式,在ARC
模式下以上的操作基本上都被在編譯階段自動(dòng)處理了。
從本質(zhì)上來(lái)講ARC
模式只不過(guò)是MRC
的升級(jí),內(nèi)存管理的機(jī)制原理是沒(méi)有變的。那么ARC
是怎樣實(shí)現(xiàn)的呢?我們先要看一看ARC
中追加的所有權(quán)聲明。
OC中為了處理對(duì)象,將變量類型定義為id
類型或各種對(duì)象類型,當(dāng)ARC
模式時(shí),id類型和對(duì)象類型必須附加所有權(quán)修飾符。所有權(quán)修飾符有以下4種:
- __strong
- __weak
- __unsafe_unretained
- __autoreleasing
__strong修飾符
__strong修飾符是id類型和對(duì)象類型的默認(rèn)所有權(quán)修飾符,也就是以下代碼
id object = [[NSObject alloc] init];
實(shí)際被附加了所有權(quán)修飾符
id __strong object = [[NSObject alloc] init];
版權(quán)聲明:出自MajorLMJ技術(shù)博客的原創(chuàng)作品 ,轉(zhuǎn)載時(shí)必須注明出處及相應(yīng)鏈接!