美文网首页ios 开发
iOS内存管理(四)ARC下__strong 和 __weak源

iOS内存管理(四)ARC下__strong 和 __weak源

作者: iOS小洁 | 来源:发表于2020-12-22 22:22 被阅读0次

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移除

相关文章

网友评论

    本文标题:iOS内存管理(四)ARC下__strong 和 __weak源

    本文链接:https://www.haomeiwen.com/subject/cveenktx.html