美文网首页
《OC高级编程》之自动引用计数(三)

《OC高级编程》之自动引用计数(三)

作者: 毛线sama | 来源:发表于2019-03-08 20:21 被阅读0次

    ARC实现

     
        ARC 由 clang (LLVM 编译器) 3.0 以上和 objc4 Objective-C 运行时库 493.9 以上实现
     

    __strong 修饰符

        2 次调用 objc_msgSend 方法(alloc 和 init),变量作用域结束时通过objc_release 释放对象,编译器自动插入 release

        用除 alloc/new/copy/mutableCopy 外方法时,release 之前调用了objc_retainAutoreleasedReturnValue 函数,与之相对的是objc_autoreleaseReturnValue 函数,用于 alloc/new/copy/mutableCopy 外等返回对象的实现,返回注册到 autoreleasepool 中的对象,但会检查使用该函数的方法或调用方的执行命令列表,如果之后紧接着调用objc_retainAutoreleasedReturnValue 函数,那么就不将对象注册到autoreleasepool,而是直接传递,即便不注册到 autoreleasepool,也可以准确获取对象,这一过程达到了最优化
     

    __weak 修饰符

    {
        id __weak obj1 = obj;
    }
    
    /* 编译器的模拟代码 */
    id obj1;
    obj1 = 0;
    objc_storeWeak(&obj1, obj);
    objc_storeWeak(&obj1, 0);
    

        objc_storeWeak 函数把第二个参数的赋值对象的地址作为键值,将第一参数的附有 __weak 修饰符的变量的地址注册到 weak 表。如果第二参数为 0,则把变量从weak 表删除

        weak 表与引用计数表相同,作为散列表实现。将废弃对象的地址作为键值进行检索,就能高效获取对应的 __ weak 变量的地址。由于一个对象可赋值给多个__weak 变量,所以对一个键值,可注册多个变量地址

        释放对象时,最后调用的 objc_clear_deallocating 函数动作如下:

    1. 从 weak 表获取废弃对象的地址作为键值的记录
    2. 将包含在记录中的所有附有 __weak 修饰符变量的地址,赋值为 nil
    3. 从 weak 表删除该记录
    4. 从引用计数表中删除废弃对象的地址为键值的记录

        可见,如果大量使用 __weak,会消耗相应的 CPU,所以只在需要避免循环引用时使用

    id __weak obj = [[NSObject alloc] init];
    id __unsafe_unretained obj = [[NSObject alloc] init];
    //编译器警告
    
    [[NSObject alloc] init];
    //ARC 无效时会发生内存泄漏
    (void)[[NSObject alloc] init];
    //避免警告
    //ARC 有效时,编译器生成并立即调用 objc_release 函数,不会造成内存泄漏
    //可以调用被立即释放的对象的实例方法,调用完就被释放
    

        访问附有 __weak 修饰符的变量时,调用了 objc_loadWeakRetained 函数和objc_autorelease 函数

    1. objc_loadWeakRetained 函数取出附有 __weak 变量所引用的对象并 retain
    2. objc_autorelease 函数将对象注册到 autoreleasepool 中

        在大量使用 __ weak 变量时,注册到 autoreleasepool 中对象也大量增加,最好先暂时赋值给附有 __strong 变量再使用

    独自实现引用计数的类大多不支持 __weak,当 allowsWeakReference/retainWeakReference 方法返回 NO 时,也不能使用,该变量将变为 nil

     

    __autoreleasing 修饰符

    没啥说的,就调用 objc_autorelease 函数
     

    引用计数

    用 _objc_rootRetainCount 函数获取引用计数值(不完全可信

    强引用持有 +1,弱引用不变,向 autoreleasepool 注册+1,访问 __weak +1

    相关文章

      网友评论

          本文标题:《OC高级编程》之自动引用计数(三)

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