Objective-C高級(jí)編程 iOS 和 OS X 多線程和內(nèi)存管理

第一章 自動(dòng)引用計(jì)數(shù)

?1.1 定義

自動(dòng)引用計(jì)數(shù)(ARC,Automatic Reference Counting)是指內(nèi)存管理中對(duì)引用采取自動(dòng)計(jì)數(shù)的技術(shù)。

*在 LLVm 編譯器中設(shè)置 ARC 為有效狀態(tài),就無需再次鍵入 retain 或者是 release 代碼。*

?1.2內(nèi)存管理/引用計(jì)數(shù)

?1.2.1概要

引用計(jì)數(shù)的機(jī)制相當(dāng)于開關(guān)房間的燈

1. 最早進(jìn)入辦公室的人開燈

2. 之后進(jìn)入辦公室的人,需要照明

3. 下班離開辦公室的人,不需要照明

4. 最后離開辦公室的人關(guān)燈(此時(shí)已無人需要照明)

判斷是否有人還在辦公室里,關(guān)鍵在于導(dǎo)入計(jì)數(shù)功能計(jì)算需要照明的人數(shù)。

1. 第一個(gè)人進(jìn)入辦公室,需要照明的人數(shù)加1.計(jì)數(shù)值從0編程了1,因此開燈

2. 之后每當(dāng)有人進(jìn)來,需要照明的人數(shù)就加1.

3. 每當(dāng)有人下班離開,需要照明的人數(shù)就減1.

4. 最后一個(gè)人下班離開辦公室時(shí),需要照明的人數(shù)減1,計(jì)數(shù)值從1變成0,因此要關(guān)燈

*對(duì)比*

```

對(duì)照明設(shè)備所做的動(dòng)作 對(duì) Objective-C 對(duì)象所做的動(dòng)作

開燈 生成對(duì)象

需要照明 持有對(duì)象

不需要照明 釋放對(duì)象

關(guān)燈 廢棄對(duì)象

```

?1.2.2 內(nèi)存管理的思考方式

* 自己生成的對(duì)象,自己所持有

* 非自己生成的對(duì)象,自己也能持有

* 不再需要自己持有的對(duì)象時(shí)釋放

* 非自己持有的對(duì)象無法釋放

```

對(duì)象操作與 Objective-C 方法的對(duì)應(yīng)

生成并持有對(duì)象 alloc/new/copy/mutablecopy 等

持有對(duì)象 retain方法

釋放對(duì)象 release 方法

廢棄對(duì)象 dealloc 方法

```

Cocoa 框架中的 Foundation 框架類庫的 NSObject 類擔(dān)負(fù)內(nèi)存管理的職責(zé)。

詳細(xì)了解內(nèi)存管理的思考方式中出現(xiàn)的各個(gè)項(xiàng)目:

*自己生成的對(duì)象,自己持有*

自己指對(duì)象的使用環(huán)境,也可以指編程人員自身

以下名稱開頭的方法自己生成自己持有

* alloc(自己生成并持有對(duì)象)

* new

* copy(生成不可變更的對(duì)象)

* mutablecopy(生成可變更的對(duì)象)

*非自己生成的對(duì)象,自己也能持有*

id obj = [NSMutableArray array];

[obj retain];

非自己生成的對(duì)象通過 retain 方法可以自己持有

*不再需要自己持有的對(duì)象時(shí)釋放*

* 自己生成并持有的對(duì)象,釋放時(shí)使用 release

* 自己生成但不持有的對(duì)象,使用 autorelease 釋放,autorelease 可以使對(duì)象在超出指定的生存范圍時(shí)能夠自動(dòng)并正確釋放

*無法釋放非自己持有的對(duì)象*

釋放之后無法再次釋放對(duì)象,也無法訪問

?alloc/retain/release/dealloc 實(shí)現(xiàn)

內(nèi)存之區(qū)域 — NSZone

是為防止內(nèi)存碎片化而引入的結(jié)構(gòu),對(duì)內(nèi)存分配的區(qū)域本身進(jìn)行多重化管理,根據(jù)使用對(duì)象的目的、對(duì)象的大小分配內(nèi)存,從而提高了內(nèi)存管理的效率。

ARC 下使用區(qū)域管理內(nèi)存反而會(huì)引起內(nèi)存使用效率低下以及源代碼復(fù)雜化等問題

源碼總結(jié):

* 在 Objective-C 的對(duì)象中存有引用計(jì)數(shù)這一整數(shù)值

* 調(diào)用 alloc 或是 retain 方法后,引用計(jì)數(shù)值加1

* 調(diào)用 release 后,引用計(jì)數(shù)值減1

* 引用計(jì)數(shù)值為0時(shí),調(diào)用 dealloc 方法廢棄對(duì)象

1.2.3 蘋果的實(shí)現(xiàn)

GNUstep采用將引用計(jì)數(shù)保存在對(duì)象占用內(nèi)存塊頭部的變量中,? 則是保存在引用計(jì)數(shù)表的記錄。

內(nèi)存塊頭部管理引用計(jì)數(shù)的好處:

* 少量代碼即可完成

* 能夠統(tǒng)一管理引用計(jì)數(shù)用內(nèi)存塊與對(duì)象用內(nèi)存塊

引用計(jì)數(shù)表管理引用計(jì)數(shù)的好處:

* 對(duì)象用內(nèi)存塊的分配無需考慮內(nèi)存塊頭部

* 引用計(jì)數(shù)表各記錄中存有內(nèi)存塊地址,可從各個(gè)記錄追溯到各對(duì)象的內(nèi)存塊

1.2.5 autorelease

autorelease 就是自動(dòng)釋放,相當(dāng)于 C 語言中的自動(dòng)變量,程序執(zhí)行時(shí),若某自動(dòng)變量超出其自動(dòng)域,該自動(dòng)變量將被自動(dòng)廢棄。想當(dāng)于會(huì)自動(dòng)調(diào)用 release 方法。

使用方法:

1. 生成并持有 NSAutoreleasePool 對(duì)象

2. 調(diào)用已分配對(duì)象的 autorelease 實(shí)例方法

3. 廢棄 NSAutoreleasePool對(duì)象

NSAutoreleasePool 由程序主循環(huán)的NSRunLoop 或者在其他程序可運(yùn)行的地方,對(duì) NSAutoreleasePool 對(duì)象進(jìn)行生成、持有和廢棄處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容