说到循环引用问题,想必大家都碰到过吧,比如在使用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. MySQL与PHP的连接教程步骤(图文)

    本篇文章我们介绍一下PHP与MySQL的整合,既然是与MySQL整合,那么我们首先肯定是要安装MySQL.下面我们就介绍下MySQL的安装方法. 第一步,下载MySQL.下载PHP可以去PHP中文网下 ...

  2. drupal的权限设置

    通过hook_menu()设置url的权限,有两种方式: 方式一:定义函数,通过 access callback 'access callback' => 'fun()', function f ...

  3. 【element+vue后台页面】Vue-element-admin

    https://segmentfault.com/a/1190000009275424

  4. 微服务架构之spring cloud ribbon

    现在负载均衡是通用的解决分压的技术方案,实现方式一般分为服务端或者客户端,服务端大部分是使用中间件实现,spring cloud ribbon 是一个客户端负载均衡组件.跟spring cloud e ...

  5. SpringBoot 整合 Mybatis + Mysql——XML配置方式

    一.介绍 SpringBoot有两种方法与数据库建立连接,一种是集成Mybatis,另一种用JdbcTemplate,本文主要讨论集成Mybatis方式. SpringBoot整合Mybatis也有两 ...

  6. android studio 3.0 以上 查看sharedpreference

    android studio 3.0 以上 查看sharedpreference 点击android studio 右侧的device file explore,找到data / data 目录: 找 ...

  7. spring boot(3)-Rest风格接口

    Rest接口 虽然现在还有很多人在用jsp,但是其实这种动态页面早已过时,现在前端流行的是静态HTML+ rest接口(json格式).当然,如果是单台服务器,用动态还是静态页面可能没什么很大区别,但 ...

  8. 在oracle电子商务套件中输出信息

    一.用自定义用户HAND_SL登陆http://zd01.haasgz.hand-china.com:30000/ 添加可执行并发程序 执行文件名填写自己的包名称.入口函数/过程名 二.将可执行程序添 ...

  9. 最优化作业 共轭梯度法 matlab代码

    syms f x1 x2 f=(1/2)*x1^2+x2^2; x=[2;1]; a=[1 0;0 2];% A g1=diff(f,x1); g2=diff(f,x2); g=[g1;g2];%导数 ...

  10. php给图片加文字

    在图片上加文字是论坛,博客,新闻网站上最喜欢用的功能,防止盗图.这里看看代码是如何实现的. 首先还是upload_image.php这个文件,注意这里的caption文本框中输入的内容最终会写到图片上 ...