众所周知,当某个对象持有着一个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内的强引用的更多相关文章

  1. 避免Block中的强引用环

    [避免Block中的强引用环] In manual reference counting mode, __block id x; has the effect of not retaining x. ...

  2. IOS block 对象强引用和若引用

    1. 在block外面这样:__weak MyController *weakSelf = self 或者 __weak __typeof(self) weakSelf = self;是为了防止强引用 ...

  3. 弱引用?强引用?未持有?额滴神啊-- Swift 引用计数指导

    ARC ARC 苹果版本的自动内存管理的编译时间特性.它代表了自动引用计数(Automatic Reference Counting).也就是对于一个对象来说,只有在引用计数为0的情况下内存才会被释放 ...

  4. Swift-08-闭包引起的循环强引用

    循环强引用还会发生在当你将一个闭包赋值给类实例的某个实例,并且这个闭包体中又实用了这个类实例.这个闭包体重可能访问了实例的某个属性,例如self.**,或者闭包中调用了实例的某个方法,例如self.* ...

  5. 关于C语言中的强符号、弱符号、强引用和弱引用的一些陋见,欢迎指正

    首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...

  6. 浅谈C语言中的强符号、弱符号、强引用和弱引用

    摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...

  7. Java -强引用&弱引用

    ⑴强引用(StrongReference) 就是通过new得的对象引用 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMe ...

  8. 用block解决nstimer循环引用

    大多数开发者可能都会这样来实现定时器.创建定时器的时候,由于目标对象是self,所以要保留此实例.然而,因为定时器是用实例变量存放的,所以实例也保留了定时器,这就造成了循环引用.除非调用stop方法, ...

  9. ios NSTimer的强引用问题

    在一个controller中,使用 NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest ...

随机推荐

  1. 生命周期-初识IOS

    经常因为生命周期的事情,而视图顺序加载错误,或者出现一系列的小错误并且修改不出来,程序员不知道生命周期确实挺可悲的. IOS生命周期: 自上而下的执行,并且viewDidLoad只会执行一次,所以我们 ...

  2. 关于C语言中的inline

    在c中,为了解决一些频繁调用的小函数大量消耗栈空间或是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数.栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的 ...

  3. 在cygwin下编译c语言

    #include <stdio.h> int main (void) { printf("Hello World!\n"); ; } 1.保存到cygwin工作目录下 ...

  4. css-盒模型,浮动,定位之间的关系

    网站布局属性:盒模型:调整元素间距float浮动:竖排的块级元素改成横排position定位:重叠元素,精确控制元素位置 能用盒模型,不用float,能用浮动,不用定位

  5. Javascript进阶篇——(DOM—认识DOM、ByName、ByTagName)—笔记整理

    认识DOM文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 将HTML代码分解 ...

  6. Asp.Net中的消息处理---MSMQ系列学习(一)

    刚刚毕业一年,比较浮躁,上次面试被问到消息队列,觉得非常的惭愧因为不知道,所以下定决心一定要学会使用它.以前只是听说过有这么个东西,要说是什么,在什么场景下使用却是无从知晓,因为自己也确实没有在项目中 ...

  7. Oracle查找重复数据

    Select * From 表 Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(*)>1)

  8. C#操作Flash动画

    对于在C#开发的过程中没有接触过Flash相关开发的人员来说,没有系统的资料进行学习,那么这篇文档针对于初学者来说是很好的学习DEMO. 本文章中的DEMO实现了C#的COM控件库中本来就带有对fla ...

  9. 遍历String字符串,得到出现次数最多的字母

    //There is no need to explain the code right? package com.hp.test; import java.util.HashMap; import ...

  10. ecshop中404错误页面设置

    在ecshop系统当中,比如你随意将商品详细页面的地址中的ID修改为一个不存在的商品ID,ecshop会自动跳转到首页.ecshop在这方面做得非常的差,甚至导致了很多的站不被搜索引擎收录.最模板提供 ...