系統提供的有不同的內存管理方案,大致有如下三種:
- TaggedPointer (對於一些小對象,比如說NSNumber等採用此種方案)
- NONPOINTER_ISA (64位架構下iOS應用程序)
- 散列表 (散列表爲複雜的數據結構,包含了引用計數表和弱引用表)
NONPOINTER_ISA
indexed:0:這裏存的是當前對象的類對象地址;1:除地址外還有內存管理方面數據
has_assoc:當前對象是否有關聯對象
has_cxx_dtor:當前對象是否有使用到C++方面的內容
shiftcls:當前對象類對象的指針地址
wealy_referenced:是否有相應的弱引用指針
deallocting:是否正在進行dealloc操作
has_sidetable_rc:是否內存管理數據過大,過大或用sidetable儲存
extra_rc:儲存內存管理相關
散列表方式
alloc
用alloc的時候並沒有引用計數+1,通過一系列調用,最終調用c函數的calloc;
dealloc:
可以看到執行過程比較簡單,_objc_rootDealloc -> rootDealloc -> objc_object::rootDealloc,
在objc_object::rootDealloc中判斷對象的幾個條件:
- isa.nonpointer,32位系統和64位系統isa的結構不同,爲0表示isa直接指向對象的class,爲1表示isa不是直接指向class
- 是否有註冊weak引用表
- 是否有association關聯屬性
- 是否有c++析構
- 是否有引用計數表
在object_dispose中調用objc_destructInstance主要做了以下操作:
- object_cxxDestruct,這裏主要是用於釋放對象的實例變量
- _object_remove_assocations,移除掉所有關聯屬性,即通過objc_setAssociatedObject添加的關聯屬性
- clearDeallocating,先清空weak變量表且將所有weak引用指向nil,然後清空引用計數表。
最後通過free函數清除對象內存。