中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS內存管理中引用計數的學習

發布時間:2020-09-11 07:17:53 來源:腳本之家 閱讀:230 作者:windtersharp 欄目:移動開發

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++實現的類,類結構如圖:

iOS內存管理中引用計數的學習

  • magic 用來校驗 AutoreleasePoolPage 的結構是否完整;
  • next 指向最新添加的 autoreleased 對象的下一個位置,初始化時指向 begin() ;
  • thread 指向當前線程;
  • parent 指向父結點,第一個結點的 parent 值為 nil ;
  • child 指向子結點,最后一個結點的 child 值為 nil ;
  • depth 代表深度,從 0 開始,往后遞增 1;
  • hiwat 代表 high water mark 。

AutoreleasePoolPage每個對象會開辟4096字節內存(也就是虛擬內存一頁的大小),除了實例變量所占空間,剩下的空間全部用來儲存autorelease對象的地址。內存結構如圖:

iOS內存管理中引用計數的學習

在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有效的編譯方法如下:

  • 使用clang(LLVM編譯器)3.0或以上版本。
  • 指定編譯器屬性為”-fobjc-arc“。

3.引用計數查看

Apple 提供一些方法查看對象的引用計數,但是并不能完全信任這些函數提供的引用計數值。對于已釋放的對象一級不正確的對象地址,有時 也返回”1“,在多線程中,因為存在競態條件的問題,所以取得的的數值不一定可信。

[object retainCount]; //得到object的引用計數,此方法僅僅適用于MRC
 _objc_rootRetainCount(obj); //MRC和ARC都適用

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

介休市| 二连浩特市| 莫力| 宜川县| 宁河县| 白沙| 咸宁市| 十堰市| 德兴市| 运城市| 河北省| 新郑市| 金平| 虞城县| 勃利县| 凤庆县| 辛集市| 兰西县| 栾川县| 武隆县| 澳门| 阿克陶县| 朝阳市| 兰西县| 大洼县| 敦化市| 祁连县| 拜城县| 兴和县| 永宁县| 布拖县| 长顺县| 日喀则市| 双峰县| 武宁县| 土默特右旗| 明溪县| 育儿| 贵州省| 锡林郭勒盟| 马关县|