iOS 引用计数实现原理(alloc,retain,release,retainCount,dealloc)

iOS 引用计数实现原理(alloc,retain,release,retainCount,dealloc)

alloc

系统经过调用之后会调用到c函数calloc,但是此时并没有设置引用计数为1

retain

其实就是系统去引用计数表,也就是sideTables中去查找,sizeTable,通过当前对象的指针去获取,SideTable &table = SideTables()[this]上篇文章有介绍过什么事sideTable,当找到sideTable之后,再获取引用计数size_t $refcntStorage = table.refcnts[this] refcntStorage += SIDE_TABLE_RC_ONE,其实也是hash查找,size_t 就是 unsigned long,查找到之后在进行加法操作

release

和上面查找方式一样,只不过做减1操作 refcntStorage -= SIDE_TABLE_RC_ONE

retainCount

SideTable &table = sideTables()[this];

size_t refcnt_result = 1;

RefcountMap::iterator it = table.refcnts.find(this);

refcnt_resount+= it->second>>SIDE_TABLE_RC_SHIFT

其实就是结合 size_t refcnt_result 这个局部变量操作的,刚新 alloc 出来的对象,在引用计数表中是没有引用计数的,之所以 retainCount 能获取到1,就是上面的原因,refcnt_resount+= it->second>>SIDE_TABLE_RC_SHIFT。

dealloc

在调用dealloc 之后,会经过 _objc_rootDealloc(),到 rootDealloc(),然后判断是否可以释放?判断释放的条件比较关键

1.nonpointer_isa,判断是否为这个isa指针类型,是否为非指针型的isa,之前文章讲过

2.weakly_referenced,是否有弱引用

3.has_assoc,是否有关联对象

4.has_cxx_dtor,判断是否有C++实现或者arc的实现

5.has_sideTable_rc,引用计数是否在sideTable中有存储

如果有一个满足条件,调用 object_disponse(),再开始释放\

object_disponse() 实现:

先判断是否有C++实现,然后判断是否有关联对象,如果没有c++,也没有关联对象,则调用object_cxxDestruct()和_object_remove_assocaations来分别释放,接下来会调用clearDeallocating方法,在这个方法中会调用sidetable_calearDeallocationg() 和 weak_clear_no_lock()两个方法,作用是指向该对象的弱引用指针置为nil,这就是为什么我们不需要再dealloc中将指向他的弱引用指针置为nil的原因,接下来会调用table.refcnts.erase(),来进行引用计数的擦除操作,然后结束流程

你可能感兴趣的:(iOS 引用计数实现原理(alloc,retain,release,retainCount,dealloc))