说到循环引用问题,想必大家都碰到过吧,比如在使用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. react生命周期es6

    基本函数有 import React from 'react' export default class MyClass extends React.Component { constructor(p ...

  2. html技巧

    1.防止盒子透出的解决办法    overflow:hidden:float不为none:display:inline-block:    position不为static&relative  ...

  3. Hololens开发笔记:UDP接收数据

    Hololens的应用需要与其他设备通信的时候,UDP是比较方便的一种方式,Unity3d 2017.3 C#开发的时候可以用Windows.Networking.Sockets.DatagramSo ...

  4. seacms 6.45 命令执行漏洞分析

    前言 这是一个比较老的漏洞了,不过漏洞原理还是挺有意思的. 正文 漏洞位于 search.php 文件中. 首先包含了 common.php, 这个文件里面做了一些初始化工作,其中最重要的是对提交参数 ...

  5. 微信小程序一个页面多个按钮分享怎么处理

    首先呢,第一步先看api文档: 组件:button https://developers.weixin.qq.com/miniprogram/dev/component/button.html 框架- ...

  6. androidcookie存储sqllite

    /**声明一些数据库操作的常量*/  private static SQLiteDatabase mDatabase = null;  private static final String DATA ...

  7. C#模拟HTTP POST 请求

    GET请求: /// <summary> /// 获取accessToken /// </summary> /// <param name="corpid&qu ...

  8. Django 代码初体验

    其实Django中的代码逻辑就是和我们以前所学的一些项目差不多 就是 解耦.解耦.解耦 创建过后的Django文件 其中的day68是你的 项目的名字的相同的一个自动生成的文件里面都是放置配置文件类似 ...

  9. 我的JS历史知识

    话说在那long long ago的1995以前,绝大多数因特网用户都使用速度仅28.8kbit/s的猫(调制调解器)上网,人们注册成为某个网站的用户时,填写好资料,发送给服务器去验证,如果某一资料填 ...

  10. CAGradientLayer实现图片渐变透明效果

    CAGradientLayer实现图片渐变透明效果 要实现的效果如下: 源码: // // RootViewController.m // CAGradientLayer // // Copyrigh ...