• 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

  • 相关阅读:
    贪心算法学习——最大数
    【算法专题】双指针
    关心过业务系统里面的sql耗时吗?统计过慢查询吗?对慢查询都怎么优化过?
    [极客大挑战 2019]Upload 1
    angular ag-grid api
    专访|OpenTiny 社区 Mr 栋:结合兴趣,明确定位,在开源中给自己一些技术性挑战
    Github又悄悄升级了,这次的变化是大文件的存储方式
    Git clone Unsupported proxy syntax in ‘proxy:port‘
    表白墙程序
    APP应用加固实战案例:贪玩蓝月
  • 原文地址:https://blog.csdn.net/ZTLVV/article/details/126032289