typedef struct objc_object NSObject;
typedef struct objc_class *Class;
typedef struct objc_object *id;
正常来说是使用传进来的cls来初始化isa 因为在创建的时候每个对象会调用[[A alloc]init] init就会调用alloc alloc会传入self 这个self就是A的对象 就是型参 Class cls 比如
bool dtor = cls->hasCxxDtor() 然后initIsa(cls,dtor)就可以用来初始化isa
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
在initIsa中 isa_t newisa(0)
是一个联合体 因为使用联合体+位域 所以只占用一个指针的空间
除了存储指针值还保存了其他信息 比如
nonpointer
占用1bit,标识是否开启isa优化.如果是一个指针值该位为0,则表示当前结构的值只是一个指针没有保存其他信息;如果为1,则表示当前结构不是指针,而是一个包含了其他信息的位域结构
has_assoc
当前对象是否使用objc_setAssociatedObject动态绑定了额外的属性
has_cxx_ctor
是否有C++的构造函数
has_cxx_dtor
是否含有C++或者OC的析构函数,不包含析构函数时对象释放速度会更快
shiftcls
这个值相当于早期实现中的isa指针,是真实的指针值,在arm64处理器上只占据33位,可见其实在内存中可以用来存储对象指针的空间是很有限的
magic
用于判断对象是否已经完成了初始化,在arm64中0x16是调试器判断当前对象是真的对象还是没有初始化的空间(在x86_64中该值为0x3b)
weakly_referenced
是否是弱引用对象
deallocating
对象是否正在执行析构函数(是否在释放内存)
has_sidetable_rc
判断是否需要用sidetable去处理引用计数
extra_rc
存储该对象的引用计数值减一后的结果. 当对象的引用计数使用extra_rc足以存储时
unused
对象是否被释放
has_sidetable_rc=0
当对象的引用计数使用extra_rc不能存储时has_sidetable_rc=1.可见对象的引用计数主要存储在两个地方:如果isa中extra_rc足以存储则存储在isa的位域中;如果isa位域不足以存储,就会使用sidetable去存储。
参考网站
alloc->_objc_rootAlloc->callAlloc->allocWithZone(和alloc)->_objc_rootAllocWithZone->initInstanceIsa
init只是把对象返回
release会调用rootRelease
如果newisa.nonpointer = 0 则调用sidetable_release方法
sidetable_release会看是否符合条件
if (do_dealloc && performDealloc) {
((void(*)(objc_object *, SEL))objc_msgSend)(this, @selector(dealloc));
会判断sidetable中refcnt是否小于SIDE_TABLE_DEALLOCATING 如果小于则表示这个对象要被释放,则调用dealloc方法。如果不小于则直接执行refcnt -= SIDE_TABLE_RC_ONE;即refcnt-1操作。
如果newisa.nonpointer = 1 则 对newisa.extra_rc进行-1操作,然后判断newisa.extra_rc是否有向下溢出,并执行对应操作。
rootDealloc会调用object_dispose
object_dispose调用free
会调用
objc_destructInstance(anObject);//会查看一下has_cxx_dtor是否有析构函数 如果有就调用他的析构 再查看是否有关联对象 如果有就取消关联 然后会做一个clearDeallocating不知道干嘛的
然后用freedObjectClass来设置Isa 将isa里面的信息都设置为nil
anObject->initIsa(_objc_getFreedObjectClass ());
最后调用
free(anObject);//调用dealloc
void *objc_destructInstance(id obj)
{
if (obj) {
Class isa = obj->getIsa();
if (isa->hasCxxDtor()) {
object_cxxDestruct(obj);
}
if (isa->instancesHaveAssociatedObjects()) {
_object_remove_assocations(obj);
}
objc_clear_deallocating(obj);
}
return obj;
}
static const void* freedObjectClass[12] =
{
Nil, // isa
Nil, // superclass
"FREED(id)", // name
0, // version
0, // info
0, // instance_size
nil, // ivars
nil, // methodLists
(Cache) &_objc_empty_cache, // cache
nil, // protocols
nil, // ivar_layout;
nil // ext
};