美文网首页
iOS日记4-weak关键字

iOS日记4-weak关键字

作者: Mcyboy007 | 来源:发表于2017-02-09 19:15 被阅读0次

    1.runtime中如何实现weak

    • 生成weak对象
    {
      //obj是__strong修饰且被赋值的对象
      id __weak obj1 = obj;
    }
    
    //编译器的模拟代码
    //转化1
    id obj1;
    objc_initWeak(&obj1, obj);
    objc_destroyWeak(&obj1);  //作用域结束,释放对象
    
    //转化2
    id obj1;
    obj1 = 0;
    objc_storeWeak(&obj1, obj);
    objc_storeWeak(&obj1, 0);
    

    weak对象有一张weak表(类似引用计数表),是作为散列表被实现。赋值对象(obj)的内存地址作为key,weak对象(obj1)的内存地址作为value存储。一个objc可以赋值给多个weak对象,所以一个key可以对应多个value。

    • 释放weak对象

    (1) objc_release
    (2) 引用计数为0,执行dealloc
    (3) _objc_rootDealloc
    (4) object_dispose
    (5) objc_destructInstance
    (6) objc_clear_deallocating

    主要讲一下第(6)步,它做的事情有:
    1)从weak表中获取weak对象的地址为键值的记录
    2)将包含在记录中所有附有__weak修饰符变量的地址,赋值为nil
    3)从weak表中删除该记录
    4)从引用计数表中删除weak对象的地址为键值的记录

    2.__weak对象与autoreleasepool的关系

    __weak修饰符的变量,会注册到autoreleasepool中
    {
      //obj是__strong修饰且被赋值的对象
      id __weak obj1 = obj;
      NSLog(@"%@", obj1);
    }
    
    //编译器的模拟代码
    id obj1;
    objc_initWeak(&obj1, obj);
    id tmp = objc_loadWeakRetained(&obj1);
    objc_autorelease(tmp);
    NSLog(@"%@", obj1);
    objc_destroyWeak(&obj1);  //作用域结束,释放对象
    

    objc_loadWeakRetained函数取出附有__weak修饰符变量所引用的对象,并retain
    objc_autorelease函数将对象注册到autoreleasepool中

    所以,如果大量使用附有weak修饰符的变量,注册到autoreleasepool的对象也会大量增加。解决办法:最好先暂时将weak对象赋值给strong修饰符的变量后再使用

    相关文章

      网友评论

          本文标题:iOS日记4-weak关键字

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