首先來看下c++
#include "isa.h"
union isa_t {
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;
uintptr_t bits;
#if defined(ISA_BITFIELD)
struct {
ISA_BITFIELD; // defined in isa.h
};
#endif
};
複製代碼
經過源碼咱們發現isa是一個聯合體union, cls 與bits是互斥關係。markdown
在看下ISA_BITFIELD宏定義 架構
# if __arm64__ //手機端
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 19
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
# elif __x86_64__ //終點架構(模擬器/mac)
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 8
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
# else
# error unknown architecture for packed isa
# endif
// SUPPORT_PACKED_ISA
#endif
複製代碼
咱們來將其簡單分享分析一下ide
位1(nonpointer) : 表示是否對isa指針開啓指針優化,0表示純isa指針,1表示不⽌是類對象地址,isa中包含了類信息、對象的引⽤計數等。函數
位2( has_assoc) : 關聯對象標誌位,1——存在,0——沒有源碼分析
位3(has_cxx_dtor): 該對象是否有C++或者Objc的析構器,若是有析構函數,則須要作析構邏輯,若是沒有,則能夠更快的釋放對象。優化
位4(shiftcls) : 存儲類指針的值。開啓指針優化的狀況下,在arm64架構中有33位⽤來存儲類指針。ui
位5(magic) : ⽤於調試器判斷當前對象是真的對象仍是沒有初始化的空間this
位6(weakly_referenced) : 對象是否被指向或者曾經指向⼀個ARC的弱變量,沒有弱引⽤的對象能夠更快釋放。spa
位7(deallocating) : 標誌對象是否正在釋放內存
位8(has_sidetable_rc) : 當對象引⽤計數⼤於10時,則須要借⽤該變量存儲進位
位9(extra_rc): 當表示該對象的引⽤計數值,其實是引⽤計數值減1, 例如,若是對象的引⽤計數爲10,那麼extra_rc爲9。若是引⽤計數⼤於10,則須要使⽤到下⾯的has_sidetable_rc
接下來咱們來看下對象釋放時候的一些處理
inline void
objc_object::rootDealloc()
{
if (isTaggedPointer()) return; // fixme necessary?
if (fastpath(isa.nonpointer &&
!isa.weakly_referenced &&
!isa.has_assoc && //關聯對象
!isa.has_cxx_dtor &&
!isa.has_sidetable_rc))//閃鏈表
{
assert(!sidetable_present());
free(this);//移除處理
}
else {
object_dispose((id)this);//釋放
}
}
id
object_dispose(id obj)
{
if (!obj) return nil;
objc_destructInstance(obj);
free(obj);
return nil;
}
objc_destructInstance(obj):
void *objc_destructInstance(id obj)
{
if (obj) {
// Read all of the flags at once for performance.
bool cxx = obj->hasCxxDtor();
bool assoc = obj->hasAssociatedObjects();//關聯對象
// This order is important.
if (cxx) object_cxxDestruct(obj);//c++ 析構
if (assoc) _object_remove_assocations(obj);//移除關聯對象
obj->clearDeallocating();
}
return obj;
}
obj->clearDeallocating():
inline void
objc_object::clearDeallocating()
{
if (slowpath(!isa.nonpointer)) {
// Slow path for raw pointer isa.
sidetable_clearDeallocating();
}
else if (slowpath(isa.weakly_referenced || isa.has_sidetable_rc)) {
// Slow path for non-pointer isa with weak refs and/or side table data.
clearDeallocating_slow();
}
assert(!sidetable_present());
}
複製代碼