您好,登錄后才能下訂單哦!
1.引用計數的思考方式
2.引用計數的實現
1.alloc方法
+ alloc + allocWithZone: class_creatInstance calloc
調用alloc方法首先調用allocWithZone:類方法,然后調用class_creatInstance函數,最后調用calloc來分配內存塊。
2.ratainCount/retain/release 方法
- retainCount __CFDoExternRefOperation CFBasicHashGetCountOfKey
- retain __CFDoExternRefOperation CFBasicHashAddValue
-retainCount __CFDoExternRefOperation CFBasicHashRemoveValue //CFBasicHashRemoveValue 為0時,-release調用dealloc
各個方法都通過同一個__CFDoExternRefOperation函數,調用一系列名稱相似的函數。并且從函數名看出蘋果采用散列表(引用計數表)來管理引用計數,表鍵值為內存塊地址的散列值。然而GNUStep將引用計數保存在對象占用內存塊頭部的變量中(objc_layout這個結構體中)。
內存塊頭部管理引用計數的好處:
引用技術表管理引用計數的好處:
1. 對象內存快的分配無需考慮內存塊頭部
引用計數表各記錄中存有內存塊地址,可從各個記錄追溯到各個內存塊。
第二條特征在調試時很重要,即使出現故障導致對象占用的內存塊損壞,但只要引用計數表沒有被損壞,就能夠確認各個內存塊的地址
3.autorelease方法
NSAutoreleasePool是通過以AutoreleasePoolPage為結點的雙向鏈表來實現的。AutoreleasePoolPage是一個C++實現的類,類結構如圖:
AutoreleasePoolPage每個對象會開辟4096字節內存(也就是虛擬內存一頁的大小),除了實例變量所占空間,剩下的空間全部用來儲存autorelease對象的地址。內存結構如圖:
在Cocoa框架中,NSRunloop每次循環過程中NSAutoreleasePool對象被生成或廢棄。在大量產生autorelease對象時,只要不廢棄NSAutoreleasePool那么生成的對象就不能被釋放,在此情況下有時會產生內存不足的現象,因此有必要適當的生成,持有和廢棄NSAutoreleasePool。通常在使用Objective-C,無論調用哪一個對象的autorelease/retain方法,實現上都是調用NSObject類的autorelease/retain實例方法,但是對于NSAutoreleasePool類,autorelease/retain實例方法已被重寫,因此運行時會出錯(exception)。autorelease實際上把對象的釋放時機交給NSAutoreleasePool管理,使用方法如下:
生成并持有NSAutoreleasePool對象。
NSAutoreleasePool *pool = [NSAutoreleasePool alloc] init]; // 等同于 objc_autoreleasePoolPush()
調用已分配對象的autorelease實例方法。
id obj = [NSObject alloc] init]; [obj autorelease]; // 等同于 objc_autorelease()obj
廢棄NSAutoreleasPool對象(自動調用分配對象的release)。
[pool drain]; // 等同于 objc_autoreleasePoolPop(pool)
4.ARC說明
ARC(Automatic Reference Counting)是編譯階段自動做了retain/release,原先需要手動添加處理引用計數的代碼可以自動地由編譯器完成。ARC并不是GC,不是運行時內存管理,不會做malloc/free的工作,它只是一種代碼靜態分析(Static Analyzer)工具,同一程序中按文件單位可以選擇ARC有效和無效。Core Foundation中的malloc()或者free()等,還是需要自己手動進行內存管理。設置ARC有效的編譯方法如下:
3.引用計數查看
Apple 提供一些方法查看對象的引用計數,但是并不能完全信任這些函數提供的引用計數值。對于已釋放的對象一級不正確的對象地址,有時 也返回”1“,在多線程中,因為存在競態條件的問題,所以取得的的數值不一定可信。
[object retainCount]; //得到object的引用計數,此方法僅僅適用于MRC _objc_rootRetainCount(obj); //MRC和ARC都適用
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。