• weak的自动置空


    __strong TObj *strongObj; 
    //__weak TObj *weakObj;
    //__unsafe_unretained TObj *unsafeObj;

    {
            TObj *obj = [[TObj alloc] init];
            NSLog(@"obj对象:%@", obj); 
            strongObj = obj; 
         //   weakObj = obj;
         //  unsafeObj = obj;
    }

    NSLog(@"strongObj:%@", strongObj);
    // NSLog(@"weakObj:%@", weakObj);
    // NSLog(@"unsafeObj:%@", unsafeObj);

    • __strong修饰后,对象的引用计数会增加,在作用域外不会销毁
    • __weak修饰后,对象引用计数不会增加,在作用域外会自动置为nil (打印weakObj为null)
    • __unsafe_unretained修饰后,兑现引用计数不会增加,在作用域外不会置空,会造成野指针崩溃

    一:weak的创建

    还是使用刚才的例子,直接跟踪汇编和打符号断点,发现底层库调了objc_initWeak函数。

    objc_initWeak

    其中两个参数locationnewObj的含义如下:

    1.location:表示__weak指针的地址,即例子中的weak指针取地址: &weakObjc 。它是一个指针的地址。之所以要存储指针的地址,是因为最后我们要讲__weak指针指向的内容置为nil,如果仅存储指针的话,是不能够完成这个功能的。
    2.newObj:所引用的对象,即例子中的obj 。

    storeWeak

    在storeWeak方法中有两个重要的方法,weak_register_no_lock 和 weak_unregister_no_lock。

    weak_register_no_lock:如果可以被弱引用,则将被弱引用对象所在的weak_table中weak_entry_t哈希数组中取出对应的weak_entry_t,如果weak_entry_t不存在,则会新建一个。然后将指向被弱引用对象地址的指针referrer通过函数append_referrer插入到对应的weak_entry_t引用数组。完成了弱引用

    weak_unregister_no_lock:如果weak指针在指向obj之前,已经弱引用了其他的对象,则需要先将weak指针从其他对象的weak_entry_thash数组中移除。在storeWeak方法中会调用weak_unregister_no_lock函数来做移除操作。

    二:weak的销毁

    weak修饰的对象,出作用域,对象dealloc后,会自动把弱引用对象置空,例如开头的例子。

    主要方法有:_objc_rootDealloc, object_dispose,weak_clear_no_lock

    weak_clear_no_lock:从sideTble中的weak_table散列表找到对应的weak_entry_t数组,然后通过遍历找到对应的指针地址,置为nil,防止了野指针的报错。

    总结

    创建和销毁差不多相同,从sideTble中的weak_table散列表找到对应的weak_entry_t数组,然后通过遍历找到对应的指针地址,置为nil,防止了野指针的报错,或者插入到weak_entry_t数组。

    • 当一个对象obj被weak指针指向时,这个weak指针会以obj作为key,被存储到sideTable类的weak_table这个散列表上对应的一个weak指针数组里面。
    • 当一个对象obj的dealloc方法被调用时,Runtime会以obj为key,从sideTableweak_table散列表中,找出对应的weak指针列表,然后将里面的weak指针逐个置为nil

  • 相关阅读:
    Bean的生命周期
    Python大数据之PySpark(四)SparkBase&Core
    因为环境导致程序运行不起来的进来看,或许对你有用
    电脑提速方法:虚拟内存使用固态硬盘
    MySql总结
    Python <算法思想集结>之抽丝剥茧聊动态规划
    基于哈希表对unordered_map和unordered_set的封装
    HarmonyOS—编译构建概述
    说说Java三种启动类路径
    python函数(8):异常处理机制+模块
  • 原文地址:https://blog.csdn.net/ZTLVV/article/details/126032289