zoukankan      html  css  js  c++  java
  • __strong修饰符

    本文用来观察,对于__strong修饰符,编译器为我们自动添加了什么代码,这些代码对于引用计数有什么影响。

    例子一

    X __strong *x1 = [[X alloc] init];

    使用控制台打印引用计数,计数值为1,符合预期:

    (lldb) p CFGetRetainCount((__bridge CFTypeRef)x1)
    (CFIndex) $0 = 1
    (lldb) 

    例子二

    X __strong *x2 = [X create]; //create返回对象X

    使用控制台查看引用计数,计数值为2:

    (lldb) p CFGetRetainCount((__bridge CFTypeRef)x2)
    (CFIndex) $1 = 2
    (lldb) 

    计数值为2,说明x2被持有了两次,使用clang的-S选项查看汇编文件:

    .loc    1 40 7 is_stmt 0        ## autorelease.m:40:7  调用[X create]的源码处
        movq    %rax, %rdi
        callq    _objc_retainAutoreleasedReturnValue  ##返回的autoreleased值被又持有了一次
        xorl    %ecx, %ecx
        movl    %ecx, %esi
        movq    %rax, -24(%rbp)

    发现编译器对于返回的autoreleased值(即由非alloc/new/init/copy/mutableCopy开头的方法返回的值)调用了一次Retain方法。

    例子三

     X __storng *x1 = [[X alloc] init];
     X __strong *x2 = x1;

    在Xcode控制台查看引用计数,结果为2,说明对__strong变量赋值操作,也会导致引用计数加1:

    (lldb) p CFGetRetainCount((__bridge CFTypeRef)x1)
    (CFIndex) $2 = 2
    (lldb) p CFGetRetainCount((__bridge CFTypeRef)x2)
    (CFIndex) $3 = 2
    (lldb) 

    查看汇编代码,发现赋值操作编译器也会自动插入Retian操作:

    .loc    1 40 7                  ## autorelease.m:40:7  调用[[X alloc] init]处
        movq    %rax, -24(%rbp)
        .loc    1 41 12 is_stmt 1       ## autorelease.m:41:12 x2 = x1处
        movq    -24(%rbp), %rax
        movq    %rax, %rdi
        callq    *_objc_retain@GOTPCREL(%rip)  ##赋值的时候,也会调用Retian方法

    总结

    对于__strong修饰符,编译器会根据情况插入Retain方法:

    1 如果是alloc/init/new/copy/mutableCopy方法或者以他们作为方法名开头的方法来给__strong变量赋值,编译器不会插入Retain方法

    2 如果是非1所指的方法,或者是把一个变量赋给一个__strong变量,编译器都会插入相应的Retain方法

  • 相关阅读:
    java小提示:标示符常见命名规则、常用ASCII
    java程序练习:数组中随机10个数中的最大值
    java第四课:数组
    java程序练习:x进制转Y进制
    java第三课:分支结构、循环结构
    java第二课:运算符和表达式
    java第一课:环境、变量、数据类型
    00
    linux 设备驱动 nand驱动框架
    linux内核源码分析plat-form 分析
  • 原文地址:https://www.cnblogs.com/chaoguo1234/p/11147204.html
Copyright © 2011-2022 走看看