引入一个nonpointer
概念
早期调用isa可以返回类,后来苹果为了优化内存,使其内部增加了及其丰富的信息,并且增加了isa_mask,不让直接获取类,有优化就是nonpointer
isa简介
从初始化isa源码入手分析
inline void
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
{
ASSERT(!isTaggedPointer());
isa_t newisa(0);
if (!nonpointer) {
newisa.setClass(cls, this);
} else {
ASSERT(!DisableNonpointerIsa);
ASSERT(!cls->instancesRequireRawIsa());
#if SUPPORT_INDEXED_ISA
ASSERT(cls->classArrayIndex() > 0);
newisa.bits = ISA_INDEX_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
newisa.bits = ISA_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
# if ISA_HAS_CXX_DTOR_BIT
newisa.has_cxx_dtor = hasCxxDtor;
# endif
newisa.setClass(cls, this);
#endif
newisa.extra_rc = 1;
}
// This write must be performed in a single store in some cases
// (for example when realizing a class because other threads
// may simultaneously try to use the class).
// fixme use atomics here to guarantee single-store and to
// guarantee memory order w.r.t. the class index table
// ...but not too atomic because we don't want to hurt instantiation
isa = newisa;
}
- ASSERT(!isTaggedPointer());
首先断言判断,是否是小对象,不是小对象,执行下面语句
isa_t newisa(0)
初始化isa_t
if (!nonpointer)
判断是否优化,未开启优化,直接关联
newisa.setClass(cls, this);
否则执行
从这里可以看出isa_t才是isa的真正的结构
isa的数据结构
代码如下
union isa_t {
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
uintptr_t bits;
private:
Class cls;
public:
#if defined(ISA_BITFIELD)
struct {
ISA_BITFIELD; // defined in isa.h
};
#endif
};
看出isa_t是联合体+位域
- 联合体大小取决于内部最大的元素的大小,所以isa大小为8字节。
- 联合体内部的元素在内存中是互相覆盖,所以cls和bits不会同时存在
联合体内部又增加了位域结构使isa更加丰富,接下来,我们来看ISA_BITFIELD
# 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 unused : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8
nonpointer
:表示是否对isa指针开启优化(0:纯isa指针,1:不止是类对象地址,还包含了类信息,对象的引用计数等)
has_assoc
:关联对象标志位(0没有,1存在)
has_cxx_dtor
:该对象是否有C++或者Objc的析构器,如果有析构函数,则需要做析构逻辑,如果没有,可以更快释放对象
shiftcls
:存储类指针的值。开启指针优化的情况,在arm64架构下,有33位用来存储类指针
magic
:用于调试器判断当前对象是真的对象,还是没有初始化的空间
weakly_referenced
:对象是否被指向或者曾经指向一个ARC的弱变量,没有弱引用的变量可以更快释放。
deallocating
:标志对象是否正在释放内存
has_sidetable_rc
:当对象的引用计数大于10时,则需要该变量存储进位
extra_rc
:表示该对象的引用计数值,实际上引用计数值减1,例如如果引用对象为10,那么该值为9,如引用计数大于10,则需要用到has_sidetable_rc
网友评论