ARC下__strong 和 __weak源码主要流程分析
一、_strong
void objc_storeStrong(id *location, id obj)
{
id prev = *location;
if (obj == prev) {
return;
}
objc_retain(obj);
*location = obj;
objc_release(prev);
}
1.1 objc_retain过程
- 1、参数为空,返回空
- 2、Taggerpoint ,返回本身
- 3、调用retain (类方法返回本身,实例方法继续调用_objc_rootRetain)
- 4、_objc_rootRetain再调用 rootRetain
- 5、rootReatain
- 5.1、rootRetain 区分taggerpoint,返回本身
- 5.2、未优化过得isa,使用sidetable_retain
- 5.3、正在释放返回nil
- 5.4、Extra_rc是未溢出isa.extra_rc+1
- 5.5、溢出将isa.extra_rc中一半转移到Sidetable中,将isa.has_sidetable_rc设置为true
1.2 objc_release 过程
- 1、objc_release --> release –>_objc_rootRelease –>rootRelease
- 2、taggerPointer 返回flase
- 3、非优化过isa,类对象返回flase,其他调用 sidetable_release
- 4、优化过isa,extre_rc—
- 5、Extra_rc下溢,从sidetable中转移引用计数到extra_rc。两者都为空时释放
1.3 retainCount流程
- 1、taggerPointer直接返回
- 2、优化过的isa,返回 1+extra_rc,如果has_sidetable_rc,再加上sidetable中计数
- 3、未优化的返回Sidetable中计数sidetable_retainCount()
- 3.1、sidetables()[this]找到Sidetable
- 3.2、sidetable.refcnts.find(this)找到对应的sidetable
二、__weak
id objc_initWeak(id *location, id newObj) {
if (!newObj) {
*location = nil;
return nil;
}
return storeWeak<DontHaveOld, DoHaveNew, DoCrashIfDeallocating>
(location, (objc_object*)newObj);
}
void objc_destroyWeak(id *location) {
(void)storeWeak<DoHaveOld, DontHaveNew, DontCrashIfDeallocating>
(location, nil);
}
2.1、storeWeak流程
函数定义
template <HaveOld haveOld, HaveNew haveNew, CrashIfDeallocating crashIfDeallocating>
static id storeWeak(id *location, objc_object *newObj)
- 1、 haveNew且有newObj,判断newObj对应类是否初始化,没有初始化就调用initializa
- 2、若location对应有旧值,就清除旧值对应的该location弱引用** weak_unregister_no_lock**
- 3、如果有新值,将location注册到新值对应的弱引用表中 ** weak_register_no_lock**
- 4、若newObj不是taggerPoint对象,则设置新值newObj的isa中weakly_referenced为1
2.2、weak_register_no_lock流程
- 1、taggerpoint直接返回
- 2、判断是否正在释放,判断是否触发crash
- 3、判断传入对象在weak_table中是否有对应的entry
- 4、有entry则将弱引用变量指针地址加入entry的referrers中
- 5、没有entry则创建新的,将指针加入entry,检查weak_table是否需要扩容
2.3、weak_unregister_no_lock流程
- 1、找到entry,将引用记录删除
- 2、移除弱引用指针后,检查entry是否为空,若为空,将entry移除
网友评论