《Objective-C高級編程》(一)ARC

一、ARC

1、自動引用計數(shù)(ARC,Automatic Reference Counting)是指內(nèi)存管理中對引用采用自動計數(shù)的技術(shù)
2、在Objective-C中使用ARC,讓編譯器來進行內(nèi)存管理,無需再次鍵入retainrelease代碼
3、ARC減少了開發(fā)工作量、降低了程序崩潰量、減少了內(nèi)存泄漏的風(fēng)險并提升了運行速度。

二、內(nèi)存管理的思考方式

1、自己生成的對象,自己所持有
alloc、new、copy、mutableCopy和已此開頭的方法名
2、非自己生成的對象,自己也能持有
retain
3、不再需要自己持有的對象時釋放
release、autorelease
4、非自己持有的對象無法釋放
dealloc

三、alloc/retain/release/dealloc在GNUstep中的實現(xiàn)

1、在Objective-C的對象中存有引用計數(shù)這一整數(shù)值
2、調(diào)用alloc或是retain方法后,引用計數(shù)值加1
3、調(diào)用release后,引用計數(shù)值減1
4、引用計數(shù)值為0時,調(diào)用dealloc方法廢棄對象

GNUstep將引用計數(shù)保存在對象占用內(nèi)存塊頭部的變量中,而蘋果的實現(xiàn)則是保存在引用計數(shù)表的記錄中。

四、所有權(quán)修飾符

1、__strong修飾符

1、id類型和對象類型默認(rèn)的所有權(quán)修飾符。
2、持有強引用的變量在超出其作用域時被廢棄,隨著強引用的失效,引用的對象會隨之釋放。

/*ARC無效*/
{
    id obj = [NSObject alloc] init];
    [obj release];
}

/*ARC有效*/
{
    id __strong obj = [[NSObject alloc] init];
}

2、__weak修飾符

1、__strong修飾符不能解決循環(huán)引用問題,循環(huán)引用引起內(nèi)存泄漏。所謂內(nèi)存泄漏就是應(yīng)當(dāng)廢棄的對象在超出其生存周期后繼續(xù)存在。使用__weak可以避免循環(huán)引用。
2、持有某對象的弱引用時,若該對象被廢棄,則此弱引用將自動置為nil。(weak原理)

3、__unsafe_unretained修飾符

1、__unsafe_unretained修飾符是不安全的所有權(quán)修飾符,用其修飾的變量不屬于編譯器的內(nèi)存管理對象。
2、賦值給附有__unsafe_unretained修飾符變量的對象在通過該變量使用時,如果沒有確保其確實存在,應(yīng)用程序就會崩潰。Thread 1: EXC_BAD_ACCESS (code=1, address=0x43c97154a938)

4、__autoreleasing修飾符

1、ARC有效時,用@autoreleasepool塊替代NSAutoreleasePool類。用附有__autoreleasing修飾符的變量替代autorelease方法。
2、編譯器會檢查方法名是否以alloc/new/copy/mutableCopy開始,如果不是則自動將返回值的對象注冊到autoreleasepool。
3、init方法返回值的對象不注冊到autoreleasepool。
4、某對象作為函數(shù)的返回值,編譯器會自動將其注冊到autoreleasepool?
4、附有__weak修飾符的變量,會注冊到autoreleasepool?
5、使用po _objc_autoreleasePoolPrint()命令調(diào)試注冊到autoreleasepool上的對象

/*ARC無效*/
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
[pool drain];

/*ARC有效*/
@autoreleasepool {
    id __autoreleasing obj = [[NSObject alloc] init];
}

五、在ARC有效的情況下,需遵守ARC的規(guī)則

1、不能使用retain/release/retainCount/autorelease
2、不能使用NSAllocateObject/NSDeallocateObject
3、須遵守內(nèi)存管理的方法命名規(guī)則
4、不要顯示調(diào)用dealloc
5、使用@autoreleasepool塊代替NSAutoreleasePool
6、不能使用NSZone
7、對象類型變量不能作為C語言結(jié)構(gòu)體的成員
8、顯示轉(zhuǎn)換idvoid*

六、ARC的實現(xiàn)

1、__weak

1、objc_storeWeak函數(shù)將賦值對象的地址作為鍵值,將附有__weak修飾符的變量的地址注冊到weak表中。
2、weak表與引用計數(shù)表相同,作為散列表被實現(xiàn)。對于一個鍵值,可注冊多個變量的地址。()
3、釋放對象的過程:
3.1、從weak表中獲取廢棄對象的地址為鍵值的記錄。
3.2、將包含在記錄中的所有附有__weak修飾符變量的地址,賦值為nil。
3.3、從weak表中刪除該記錄。
3.4、從引用計數(shù)表中刪除廢棄對象的地址為鍵值的記錄。
4、如果大量使用__weak修飾符的變量,則會消耗相應(yīng)的CPU資源。所以只在需要避免循環(huán)引用時使用。

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

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

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