Block内的强引用
众所周知,当某个对象持有着一个Block的时候,如果在Block内部使用强引用反过来持有这个对象,就会导致引用循环。为了避免引用循环,可以使用__weak修饰符,苹果的官方文档在用代码演示__weak修饰符的时候,有这么一个例子:

那么,myController持有着completionHander,在completionHander内部又用一个strongMyController反过来去持有myController,这不也是一个引用循环吗?为了探究这个问题,可以用下面的方法来测试一下:
1、编写一个类ViewController,然后在类内编写方法test,做一个疑似的引用循环:

2、然后通过一个clang命令将这个类转换成C语言代码:
clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk -fobjc-arc -stdlib=libc++ -mmacosx-version-min=10.7 -fobjc-runtime=macosx-10.7 -Wno-deprecated-declarations ViewController.m
3、由此可以得到一个cpp文件,将文件中主要的部分提取出来如下:

4、可以发现:
(1)、在Block结构体中看到,被Block捕获的变量是
ViewController *const __weak weakSelf;
所以Block本身对self的引用仍然只是弱引用,并不造成引用循环。
(2)、strongSelf只存在于Block对应的函数__ViewController__test_block_func_0里,它的生命周期只在这个函数执行的过程中,函数执行前它不会存在,函数执行完它立刻就被释放了。
(3)、所以:
①、如果函数执行前self变为nil了,那么函数不会执行,没有任何引用循环发生;
②、如果函数执行过程中self变为nil了,那么函数一开始声明的strongSelf会暂时持有着self,此时会有一个暂时的引用循环。当函数执行完(即是Block执行完),strongSelf超出作用域被释放,引用循环从这里开始打破。接下来,由于没有任何强引用持有self了,于是self被释放,最后Block也因为没有任何强引用持有它也被释放了。所有对象就都被顺利释放了。
所以最终可以确定:苹果的演示代码有可能会造成引用循环,但是只是一个暂时的、可以被打破的引用循环,不会导致内存泄漏。
Block内的强引用的更多相关文章
- 避免Block中的强引用环
[避免Block中的强引用环] In manual reference counting mode, __block id x; has the effect of not retaining x. ...
- IOS block 对象强引用和若引用
1. 在block外面这样:__weak MyController *weakSelf = self 或者 __weak __typeof(self) weakSelf = self;是为了防止强引用 ...
- 弱引用?强引用?未持有?额滴神啊-- Swift 引用计数指导
ARC ARC 苹果版本的自动内存管理的编译时间特性.它代表了自动引用计数(Automatic Reference Counting).也就是对于一个对象来说,只有在引用计数为0的情况下内存才会被释放 ...
- Swift-08-闭包引起的循环强引用
循环强引用还会发生在当你将一个闭包赋值给类实例的某个实例,并且这个闭包体中又实用了这个类实例.这个闭包体重可能访问了实例的某个属性,例如self.**,或者闭包中调用了实例的某个方法,例如self.* ...
- 关于C语言中的强符号、弱符号、强引用和弱引用的一些陋见,欢迎指正
首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...
- 浅谈C语言中的强符号、弱符号、强引用和弱引用
摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...
- Java -强引用&弱引用
⑴强引用(StrongReference) 就是通过new得的对象引用 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMe ...
- 用block解决nstimer循环引用
大多数开发者可能都会这样来实现定时器.创建定时器的时候,由于目标对象是self,所以要保留此实例.然而,因为定时器是用实例变量存放的,所以实例也保留了定时器,这就造成了循环引用.除非调用stop方法, ...
- ios NSTimer的强引用问题
在一个controller中,使用 NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest ...
随机推荐
- [RxJS] Wrap up
Last thing to do is clean the score box and input, also auto foucs on input when click start. const ...
- [RxJS] Completing a Stream with TakeWhile
Subscribe can take three params: subscribe( (x)=> console.log(x), err=> console.log(err), ()=& ...
- PHP中$_SERVER的具体參数与说明
PHP编程中常常须要用到一些server的一些资料.特把$_SERVER的具体參数整理下,方便以后使用. $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名称,与 document ...
- String源码学习
String源码学习 零散的收获 数组的元素类型可以通过getComponentType来获取到 子类型的数组可以赋值给父类型的数组,.但是并不存在继承关系.数组的父类是Object. 通过声明如下代 ...
- Tomcat 原理篇
TOMCAT 原理篇一.Tomcat 组成(Tomcat 由以下组件组成) 1.server a) Server是一个Catalina Servlet容器: b) Server 可以包含一个或多个se ...
- 从free命令看Linux内存管理
free命令是Linux系统下用来查看内存使用情况的,例如: $ free -h total used free shared buffers cached Mem: 7.8G 6.6G 1.3G 0 ...
- (转)[老老实实学WCF] 第二篇 配置WCF
第二篇 配置WCF 在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Collections. ...
- HDU 4612 (13年多校第二场1002)无向图缩点,有重边
这道题是多校的题,比赛的时候是一道纷纷水过的板刷题. 题意:给你一些无向边,只加一条边,使该图的桥最少,然后输出最少的桥. 思路:当时大致想到思路了,就是缩点之后找出最长的链,然后用总的桥数减去链上的 ...
- linux上安装apache以及httpd.conf基本配置
1.yum安装apache #yum install httpd -y 2.随系统自启动 #chkconfig httpd on 3.开启apache #service httpd start PS: ...
- 关于TP的RBAC的使用
如果你是一个TP的重度使用者的话,请自动略过笔者以下文字 权限管理我在成为一个开发者1年半内,接触过2种,一种就是数学方式 比如我们文件夹权限的755这种权限管理的方式,这种二进制的权限管理的方式 无 ...