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 ...
随机推荐
- Operation System - Peterson's Solution算法 解决多线程冲突
Person's solution 是用来一种基于软件的解决关键区域问题的算法(critical-section). 它并不是完美的,有可能不对地工作.并且是限制解决两个进程同步的问题. 可是它非常e ...
- [Redux] Passing the Store Down Implicitly via Context
We have to write a lot of boiler plate code to pass this chore down as a prop. But there is another ...
- 使用HashMap对象传递url參数有用工具类
代码例如以下: package com.yanek.util; import java.util.ArrayList; import java.util.Collections; import jav ...
- openMP的一点使用经验
最近在看多核编程.简单来说,由于现在电脑CPU一般都有两个核,4核与8核的CPU也逐渐走入了寻常百姓家,传统的单线程编程方式难以发挥多核CPU的强大功能,于是多核编程应运而生.按照我的理解,多核编程可 ...
- CSS 实现三角形、梯形、等腰梯形
三角形 ; width: 0px; border-width: 0px 30px 45px 145px; border-style: none solid solid; border-color: t ...
- Temporary ASP.NET Files 文件夹中保存的是什么内容?[转]
转自:http://www.cnblogs.com/suiqirui19872005/archive/2007/05/14/746320.html ASP.NET 页面请求的处理过程需要使用一些临时文 ...
- java equals 心得体会
要记住最有用的一点: equals 在已经被系统定义好的类中 是已经被重写好了的 父类中的 equals方法是比较的两个对象是否指向同一引用 在被定义除了父类以外比较的是两个对象的内容 因此 人为定义 ...
- iOS在MRC工程环境下下使用ARC的方法
- iscroll-lite.js源码注释
/*! iScroll v5.1.2 ~ (c) 2008-2014 Matteo Spinelli ~ http://cubiq.org/license */ (function (window, ...
- Nutch的日志系统
一.Nutch日志实现方式 1.Nutch使用slf4j作为日志接口,使用log4j作为具体实现.关于二者的基础,请参考 http://blog.csdn.net/jediael_lu/article ...