说到循环引用问题,想必大家都碰到过吧,比如在使用Block的时候,使用__weakSelf来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助。

是否所有的Block中,使用self都会导致循环引用?

答案是否定的!如下面所示的这种情况

如上,使用系统自带的UIView的Block,控制器可以被销毁,说明并没有发生循环引用。

原因:UIView调用的是类方法,当前的控制器不可能强引用一个类,所以循环无法形成,动画的block不会造成循环引用

除了系统自带的某些Block不会引起循环引用外,我们大家常使用的AFN中的block是否循环引用呢?答案如下图所示:

很明显,通过Log可以看到它不会导致循环引用

原因:AFN无循环是因为绝大部分情况下,使用的网络类是不会被当前控制器引用的,这时就不会形成引用环(查资料得知)

那什么情况下会导致循环引用呢?--> 自定义的Block

我们在viewDidKLoad中打印,在该控制器每次进入都会打印,在该控制器消失的时候,如果没有调用dealloc,说明该block引起了循环引用

如上图,我们发现log中并没有打印“-[SecondViewController viewDidLoad] --->dealloc”。说明block中使用self,导致了循环引用

导致循环引用的原因:相互强指向

解决方法:使用weakSelf

 __weak typeof(self) weakSelf = self;
_testBlock = ^ {
NSLog(@"%@",weakSelf.view);
};

如上所说,那么自定义Block是否一定会发生循环引用?

如图:我们发现oneVC被销毁了,说明自定义的Block,里面使用self,并不一定发生循环引用

原理:block-->强指向了self,但是self,并没有指向Block。并没有一个self.xxBlcok或者成员变量block,所有的block并没有被强指向,所以没有发生循环引用


既然系统的Block、AFN都不会发生循环引用,自定义的Block循环引用会有⚠️提示,那么实际开发中真的不会遇到循环引用?

在实际开发中,使用通知,调用系统自带的Block方法,在block中使用self,会发生循环引用

我们在ThirdVC中发送通知给SecondVC

在SecondVC中接收通知

当从SecondVC pop回OneVC时,SecondVC并没有调用dealloc,说明存在循环引用,当时控制器无法销毁。这是因为在通知的方法的Block中使用了self,但是这次并没有提示,不过确实是发生了循环引用!

解决方法:使用weakSelf!

总结:

以上就是全部内容了,希望对看到的各位有所帮助,如果存在疑问或者发现任何问题大家可以浏览交流。

iOS中Block循环引用的问题的更多相关文章

  1. iOS中block循环引用问题

    1.block是控制器对象的一个属性,则在block内部使用self将会引起循环应用 typedef void(^TestBlock)(); @interface SecondViewControll ...

  2. 如何在 iOS 中解决循环引用的问题

    稍有常识的人都知道在 iOS 开发时,我们经常会遇到循环引用的问题,比如两个强指针相互引用,但是这种简单的情况作为稍有经验的开发者都会轻松地查找出来. 但是遇到下面这样的情况,如果只看其实现代码,也很 ...

  3. ios 中的循环引用问题及解决

    循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存.其实有点类似死锁. 举个例子:A->B->C->....->X->B   - ...

  4. ios - block循环引用Demo示例

    当实例变量中有了block属性,并且用copy来修饰,但是当调用block中的代码的时候,如果block中运用了self.属性的时候回造成循环引用. // // ViewController.h // ...

  5. iOS Block循环引用

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  6. IOS block 循环引用的解决

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  7. iOS容易造成循环引用的三种场景

    iOS容易造成循环引用的三种场景  ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露.导致iOS对象无法按预期释放的一个无形杀手是--循环引用.循环引用可以简单理解为 ...

  8. Block循环引用详解

    前言 在项目中经常用到block,使用不当就很容易因为循环引用而造成内存泄漏.本文分析了block循环引用形成原因以及处理办法,如果有什么不对或者疑问请留言. 什么情况下block会造成循环引用 bl ...

  9. iOS中block的用法 以及和函数用法的区别

    ios中block的用法和函数的用法大致相同 但是block的用法的灵活性更高: 不带参数的block: void ^(MyBlock)() = ^{}; 调用的时候  MyBlock(); 带参数的 ...

随机推荐

  1. bootstrap框架怎么在html页面加载使用

    今天敲代码的时候,正好碰到这个问题. 与大家分享这个解决方法:     1/7 到bootstrap官方网站下载,对于我们开发者来说,直接下载编译和压缩后的CSS.JavaScript文件,另外还包含 ...

  2. css3 伪元素和伪类选择器详解

    转自脚本之家:http://www.jb51.net/css/213779.html 无论是伪类还是伪元素,都属于CSS选择器的范畴.所以它们的定义可以在CSS标准的选择器章节找到.分别是 CSS2. ...

  3. 浏览器根对象window之值为数值的属性

    1. number属性 1.1 length length 属性返回在当前窗口中frames的数量(包括IFRAMES). 该属性值与window.frames.length属性值相等. 1.2 in ...

  4. Java 中你必须了解的常用类(8)

    Java 中的包装类 相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的, 比如基本类型不能调用方法.功能 ...

  5. 纯C语言跑分(详细注释)

    #include <stdio.h> #include <time.h>//clock()所属头文件 ;//快排的数据规模 ,N=;//整点.浮点运算的规模 ;//计算圆周率的 ...

  6. Java多线程学习笔记(二)

    三 多线程执行的共享数据和非共享数据: 共享数据:就是每个线程执行的时候共享数据使用,比如这个线程一个为5的数据,减少为4之后,另一个线程执行拿到的数据是4,两个线程执行的数据是共享的. 非共享数据: ...

  7. 如何检索某个字段在sqlserver中的哪个些存储过程中?很简单的SQL语句。

    SELECT obj.Name 存储过程名, sc.TEXT 存储过程内容 FROM syscomments sc INNER JOIN sysobjects obj ON sc.Id = obj.I ...

  8. 实用的JS正则表达式(手机号码/IP正则/邮编正则/电话等)

    //校验是否全由数字组成 function isDigit(s) { var patrn=/^[0-9]{1,20}$/; if (!patrn.exec(s)) return false retur ...

  9. Python学习---PyCharm的使用学习

    1.1. IDEA的使用 PyCharm2017下载 链接:https://pan.baidu.com/s/1HPR9FtVV5BCvd3uTdOetxw 密码:ok0q 激活IDEA2017(方案一 ...

  10. CRF++ 如何制定自己的特征模板

    工具的简单介绍 对该工具的安装及介绍我这里就不再赘述,请参考官方文档或者国内一些翻译后的中文版.也还比较清楚. 我只介绍一下crf++在命名实体识别中的一些用法,这些都建立在你了解crf++的一些最基 ...