前言
自動引用計數(shù) 是指內(nèi)存管理中對引用采取自動計數(shù)的技術。
OC中ARC模式是讓編譯器來替我們實現(xiàn)內(nèi)存管理,我們無需再像在MRC模式下需要手動鍵入retain、release來進行內(nèi)存管理,不但降低了程序的出錯概率也減少了程序的書寫工作量。這里要提一下的是,擁有ARC這樣強大內(nèi)存管理模式主要依賴于3.0及以上版本的LLVM編譯器。
內(nèi)存管理
OC內(nèi)存管理的核心就是引用計數(shù)。我們以遛狗的場景為例來解釋引用計數(shù)機制:
當人物A要出門遛狗的時候,A會在狗的脖子上栓一條鏈子牽著它。然后人物B也想同時溜這條狗(當然在現(xiàn)實中這種情況比較奇葩了,我們先不考慮這個),B會在狗的脖子上再拴上一條鏈子,這時兩個人都對這條狗持有。當A不想溜了就會解開鏈子,此時狗的脖子上只有B持有的一條鏈子。當B也不想溜了,B也解開了狗脖子上的鏈子。此時狗的脖子上沒有鏈子的束縛,狗就逃掉了。
上邊情景中狗就是對象,人物在狗的脖子上拴上鏈子就是引用,解開狗脖子上的鏈子就是釋放,狗脖子上鏈子數(shù)就是引用計數(shù),當狗脖子上鏈子數(shù)為0狗會逃走,也就是當對象引用計數(shù)為0對象就被完全釋放。
下面用一個圖示解釋一下:

對象的引用計數(shù)我們可以通過
[object retainCount];獲取。
圖示中有四個動詞:生成、持有、釋放、廢棄,這四個詞分別對應OC中的哪些方法以及含義呢?
- 生成并持有:
alloc/new/copy/mutableCopy等
自己(這里的自己應該理解為生成對象的‘當前環(huán)境’)生成的對象,并持有它。 - 持有:
retain
非自己生成的對象,自己去持有它。 - 釋放:
release
不再需要自己持有的對象,釋放它。 - 廢棄:
dealloc
對象不再被需要,被銷毀。
其實這些內(nèi)存管理的方法并不是OC語言本身提供的,而是NSObject類本身肩負了內(nèi)存管理的職責,alloc是NSObject類的類方法,retain、release、dealloc是NSObject類的實例方法。
生成并持有
除了使用alloc、new、copy、mutableCopy方法外:
使用alloc、new、copy、mutableCopy開頭的方法同樣意味著自己生成并持有,如:
allocOneObject
newThatObject
copyThis
mutableCopyYourObject
...
例如:
- (id)allocObject{
id object = [[NSObject alloc] init];
return object;
}
命名規(guī)則必須遵循駝峰寫法,以下命名的方法則不屬于自己生成并持有的范疇
alloconeobject
newthatobject
...
copy、mutableCopy方法是分別依賴于NSCopying、NSMutableCopy協(xié)議,由各類實現(xiàn)的copyWithZone:、mutableCopyWithZone:方法生成并持有的對象的副本。這些方法雖然生成的是副本,但依然是自己生成并持有。
持有
除了以上的方法外,我們來看看NSMutableArray的array方法
// 取得非自己生成的對象
id object = [NSMutableArray array];
// 通過retain函數(shù),實現(xiàn)自己持有
[object retain];
釋放
當我們不在需要持有對象的時候,我們就要釋放對對象的持有,那就要用到release方法
id object = [[NSMutableArray alloc] init];
// 釋放持有
[object release];
id object = [NSMutableArray array];
[object retain];
// 釋放持有
[object release];
都可以使用release函數(shù)進行釋放
注意:我們是無法釋放非自己持有的對象的,比如:
id object = [[NSObject alloc] init];
// 釋放對象 自己不再持有
[object release];
// 當再次釋放自己已經(jīng)不再持有的對象就會報錯
[object release]; // 所以這一句代碼是錯誤的
ARC規(guī)則
上面介紹的大多數(shù)方法都是MRC模式下我們手動管理內(nèi)存的操作方式,在ARC模式下以上的操作基本上都被在編譯階段自動處理了。
從本質(zhì)上來講ARC模式只不過是MRC的升級,內(nèi)存管理的機制原理是沒有變的。那么ARC是怎樣實現(xiàn)的呢?我們先要看一看ARC中追加的所有權聲明。
OC中為了處理對象,將變量類型定義為id類型或各種對象類型,當ARC模式時,id類型和對象類型必須附加所有權修飾符。所有權修飾符有以下4種:
- __strong
- __weak
- __unsafe_unretained
- __autoreleasing
__strong修飾符
__strong修飾符是id類型和對象類型的默認所有權修飾符,也就是以下代碼
id object = [[NSObject alloc] init];
實際被附加了所有權修飾符
id __strong object = [[NSObject alloc] init];
版權聲明:出自MajorLMJ技術博客的原創(chuàng)作品 ,轉載時必須注明出處及相應鏈接!