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

例子一

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

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

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

例子二

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

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

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

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

.loc       is_stmt         ## autorelease.m::  调用[X create]的源码处
movq %rax, %rdi
callq _objc_retainAutoreleasedReturnValue ##返回的autoreleased值被又持有了一次
xorl %ecx, %ecx
movl %ecx, %esi
movq %rax, -(%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) $ =
(lldb) p CFGetRetainCount((__bridge CFTypeRef)x2)
(CFIndex) $ =
(lldb)

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

.loc                        ## autorelease.m::  调用[[X alloc] init]处
movq %rax, -(%rbp)
.loc is_stmt ## autorelease.m:: x2 = x1处
movq -(%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方法

__strong修饰符的更多相关文章

  1. Objective C中的ARC的修饰符的使用---- 学习笔记九

    #import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ...

  2. ARC下的所有权修饰符

    ARC有效时,id类型必须加上所有权修饰符 下面为三种等效的声明,为了便于和二级指针的情况联系起来,采用第一种. NSError * __weak error = nil; NSError __wea ...

  3. iOS 基础日记-修饰符

    今晚随便温习了一下iOS 基础关于修饰符这块的东西,下面简单的来描述一下,其中有的也是在网络学习到的: strong与weak是由ARC新引入的对象变量属性 ARC的解释:ARC引入了新的对象的生命周 ...

  4. __block和__weak修饰符的区别

    block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...

  5. 01 (OC)* @property 后面可以有哪些修饰符?

    一:@property 后面可以有哪些修饰符? 1:线程安全的: atomic,nonatomic 2:访问权限的 readonly,readwrite 3:内存管理(ARC) assign, cop ...

  6. JAVA语言中的修饰符

    JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...

  7. Java类访问权限修饰符

    一.概要 通过了解Java4种修饰符访问权限,能够进一步完善程序类,合理规划权限的范围,这样才能减少漏洞.提高安全性.具备表达力便于使用. 二.权限表 修饰符 同一个类 同一个包 不同包的子类 不同包 ...

  8. iOS 方法修饰符

     一.NS_DESIGNATED_INITIALIZER 用来修饰init方法,被修饰的方法称为designated initializer:没有被这个修饰的init方法称为convenience i ...

  9. C#基础回顾(一)—C#访问修饰符

    一.写在前面的话 好久没有停下来总结自己,转眼间15年过去好些天,回首过去的日子,亦或失去,亦或所得!生活的节奏,常常让我们带着急急忙忙的节奏去追赶,也许这并不是每个人所期望的生活方式!于他人,于自己 ...

随机推荐

  1. 并行计算基础(1)(GPU架构介绍)

    一.常用术语 Task:任务.可以完整得到结果的一个程序,一个程序段或若干个程序段.例如搬砖. Parallel Task:并行任务.可以并行计算的任务.多个人搬砖. Serial Execution ...

  2. Java多线程和并发(十二),Java线程池

    目录 1.利用Executors创建线程的五种不同方式 2.为什么要使用线程池 3.Executor的框架 4.J.U.C的三个Executor接口 5.ThreadPoolExecutor 6.线程 ...

  3. Python天天学_02_基础二

    Python_day_02 金角大王:http://www.cnblogs.com/alex3714/articles/5717620.html ------Python是一个优雅的大姐姐 学习方式: ...

  4. Codeforces 343D Water Tree & 树链剖分教程

    原题链接 题目大意 给定一棵根为1,初始时所有节点值为0的树,进行以下三个操作: 将以某点为根的子树节点值都变为1 将某个节点及其祖先的值都变为0 *询问某个节点的值 解题思路 这是一道裸的树链剖分题 ...

  5. crm 项目的部署

    发布CRM你将使用以下软件 nginx uWSGI CentOS7 CRM项目文件 virtualenv supervisor WSGI.uWSGI python web服务器开发使用WSGI协议(W ...

  6. springboot学习问题一:启动springboot报错端口被占用解决办法

    一:问题 二:分析原因 springboot启动默认端口为8080,现在提示被占用,那我们可以修改springboot的启动端口,换一个未被占用的端口即可 三:解决方法 打开application.p ...

  7. 网络安全监控实战(一):Snort,Wazuh&VT

    https://cloud.tencent.com/developer/news/222711

  8. yum源相关

    yum软件仓库默认配置文件/etc/yum.conf,此文件定义了yum在线下载的rpm包存放位置及下载后是否保存. [root@localhost ~]# head /etc/yum.conf[ma ...

  9. 用layui的 form.on提交表单如何禁止刷新页面

    答:只需要在 form.on里面的底部添加return false;即可 例如: form.on('submit(component-form-demo1)', function(data){ var ...

  10. Mac下破解百度网盘限速(Chrome + Aria2GUI)

    基本原理是利用Aria2GUI的多线程下载来达到提速的目的,具体步骤如下: 1.下载Aria2GUI客户端(注意,客户端文件要放入‘应用程序’,否则会报错),使用时注意修改线程数,默认为16,不够用, ...