iOS开发过程中,势必经常碰到block编程,大有替代delegate之势,但无论是delegate还是block都存在一个奇葩的现象:

回环引用或叫循环引用

你中有我,我中有你,双方缠绕纠结在一起,这样就会出现内存该释放的时候释放不了了!出现几次还罢,但是倘或经常性的用到某类,那内存的积攒效应将是暴发式的,总会到让你的APP内存不足的时候,而这些如果在你不明就理的情况下根本不知道原因在何处!

注意这8个字!你中有我,我中有你,这是造成回环引用的起因!并不是说本类里面所有的block里面使用self或者是访问本类成员属性就会发生回环引用!而是这个block是self的一个属性即self持有这个block时才会发生!

比如如下的就不会发生加环引用:

void(^block)(void) = ^() 

{

NSLog(@"%@", self);

};

block();

[UIView animateWithDuration:0.5 animations:^

{

NSLog(@"%@", self);

}];


故block里面使用self或者是访问成员属性并不一定会造成回环引用


下面我们来分析,以代码为例进行全面的分析这个变态的东西究竟是什么!首先,我们 来看在MRC模式下的问题。

我们定义一个简单的类:

AnObject.h如下

AnObject.m如下


我们现在一切就续,现在进行问题分析。

现在我们来初始化此类,运行此段代码,来查看引用计数器retainCount的值。

可以看到在未调用本类的方法或者是成员类的情况下,此类self的引用计数器始终是1!

进行release操作,再看看是否会调用其dealloc析构方法。

可以看到内存管理完全没有问题,在release之后试图去设置其成员arr,黄色标所示,这个时候崩溃了!崩溃的原因这儿就不必赘述!

现在我们其类在初始化方法又叫构造方法init里面的block中访问此类的成员,去掉注释行。我们看看内存引用计数器的变化。我们只是访问其arr成员,是直接访问,而不是通过self.arr来访问,我们看看内存引用计数器有什么异同!

这简直是要上天的节奏!为什么这个block会将本类的引用计数器+1?不急,我们再看看,通过self.arr来访问会是什么情况!

我们看到,无论是通过直接访问成员属性还是通过self.XXX在block里面进行访问均会导致self内存计数器+1!

网上大部分帖子都表述为"block里面引用了self导致循环引用",去你奶奶个腿儿,在此更正,只要在block里面访问本类的成员属性方法均会导致回环引用!

再看看当手动release的时候会发生什么!

根本没有调用此类里面的dealloc方法,release之后仍然可以对其成员进行访问设置数据!也就是说此处内存没有被释放,将常驻内存!

为什么?如果在block内部你进行了self.XXX或者是self的成员属性访问,block担心它在访问这些属性或者是方法的时候,self被release了,它就访问不到了!故,在某一个block的内部访问此类的成员或者是属性的时候,block就会对此类进行强引用!即计数器+1!而如果稍不注意,在MRC模式下,编译器根本不给你警告!而ARC模式下编译器会给你警告(在本文最后给你证据),你可以从容的处理,所以在MRC模式下,一定要注意!

那么在MRC模式下,一定要访问此类的成员属性怎么办?解决方案是我们得明确的告诉block,亲,不要对self强引用!我们给你一个self的弱化指针,你通过这个来访问,可以不!block说,当然可以,你给我就是了,我不会给你偷偷的再造成麻烦!~~~~~

__block typeof(self) weakSelf = self

这样,block就不会再给你造成任何麻烦!该释放的时候正常释放,不该访问的时候进行访问就崩溃!

搞明白原因,我们便不再怕这个回环引用导致的内存泄露或者是暴增问题。而ARC模式下,只是将__block 标记换为__weak标记就行了,目的都是一样的!

有些人问了,为什么把上面的

retainCount = [self retainCount];

去掉了?我去尼妹个腿!ARC模式下不允许访问类的引用计数器,你访问就报错!如果要兼容ios4.3,则用__unsafe_unretained代替__weak!

前文提到,在ARC模式下,回环引用会被编译器直接提示出来,很明确的告诉开发人员,出现了引用问题!这个就很好,期待什么时候MRC编译器也会这样提示就好了!

补充一下,如下写法,也不会导致回环引用!你自己去想想为什么吧!!!一般人我不知道他。。。

写法一:



写法二


就写这些吧,忙去鸟。。。

OC block的回环引用相关推荐

  1. segMatch:基于3D点云分割的回环检测

    该论文的地址是:https://arxiv.org/pdf/1609.07720.pdf segmatch是一个提供车辆的回环检测的技术,使用提取和匹配分割的三维激光点云技术.分割的例子可以在下面的图 ...

  2. iOS - OC Block 代码块

    前言 Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递.Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.Block 是 C 语言的,类似于一个 ...

  3. linux 增加回环设备,linux命令练习:mount fdisk swap dd创建本地回环设备

    练习一 1.创建一个1G的分区,文件系统为ext4,卷标为MYDATA,块大小为1024,预留管理空间为磁盘 分区的3%,要求开机后制动挂载至/data目录,并且自动挂载的设备要使用卷标进行引用. f ...

  4. 回环设备(loop-back devices)

    回环设备( 'loopback device')允许用户以一个普通磁盘文件虚拟一个块设备.设想一个磁盘设备,对它的所有读写操作都将被重定向到读写一个名为 disk-image 的普通文件而非操作实际磁 ...

  5. OC和Swift中循环引用的问题

    总结一下自己对OC中和Swift中循环引用的认识. 一.OC中的循环引用分为类中的循环引用和对象之间的循环引用. 1.类的循环引用 造成原因: 在两个类的.h文件中使用了#import "& ...

  6. ORB-SLAM3从理论到代码实现(六):地图回环优化

    1. 前言 LoopClosing.cc这个文件是闭环检测与矫正的代码,其逻辑比较清晰.由于用到了多地图集,所以闭环检测不仅在当前地图中进行,还会在以前的地图中检测.如果是在当前地图中检测到了回环,则 ...

  7. 【SLAM学习笔记】11-ORB_SLAM3关键源码分析⑨ Optimizer(六)地图回环优化

    2021SC@SDUSC 目录 1.前言 2.代码分析 1.前言 这一部分代码量巨大,查阅了很多资料结合来看的代码,将分为以下部分进行分析 单帧优化 局部地图优化 全局优化 尺度与重力优化 sim3优 ...

  8. 基于 2D 激光雷达和实时回环优化的 SLAM 算法

    基于 2D 激光雷达和实时回环优化的 SLAM 算法 原文: https://www.ixueshu.com/document/771d692c7d3c0c40318947a18e7f9386.htm ...

  9. AXI VDMA回环测试

    Block Design 搭建如下图所示的硬件系统: 该硬件系统的数据流向为: DDR–>AXI VDMA–>AXI DATA FIFO–>AXI VDMA–>DDR 即将一幅 ...

最新文章

  1. ICLR 2022:AI如何识别“没见过的东西”?
  2. ip代理服务器软件25探索云速捷_IP代理在实际使用过程中会面临的问题,如何准确挑选和使用代理IP...
  3. Deep Learning源代码收集-持续更新…
  4. Maven2 的常用命令
  5. tomcat配置mysql数据源_Tomcat中配置mysql数据源
  6. accp8.0 网页编程_某程序员月入上万!为何却说:我希望自己从来没有学过编程? - C/C++爱好者...
  7. 初学linux网络服务之HTTP服务实验
  8. Makefile:宏定义EXTRA_CFLAGS += -D 与CONFIG_ =y
  9. iOS 使用fopen返回null
  10. 用freeswitch建立呼叫中心系统的经验
  11. matlab 读取mdf文件路径,从 MDF 文件中读取数据
  12. From Mother Teresa
  13. 基于GoLang实现API短信网关
  14. 任正非谈成功秘诀:28年只对准一个城墙口冲锋
  15. PaddlePaddle笔记4-看图写诗
  16. oracle冷备修改数据文件位置,Oracle冷备迁移脚本(文件系统)
  17. 使用蒙特卡罗方法计算圆周率π Python
  18. JAVA语言的介绍和特性
  19. Idea相关操作以及相关问题
  20. 快捷录播服务器怎么显示时间,全场景高清录播服务器 自动高清录播系统 方便携带 搭建快捷...

热门文章

  1. 基于IFB对网络入口流量设置Qos策略
  2. 初学larval 第一篇(大神绕道哦,针对新手友好的一篇)
  3. 第二课 SS7信令系统网络简介
  4. 基因数据处理54之bwa-mem运行paird-end(1千万条100bp的reads)
  5. 世界上最复杂的函数_世界上最伟大的十大公式,你都知道哪些?
  6. HDFS集群管理与运维+distcp工具的使用
  7. sxt_(001_002)_web简介
  8. 自己拥有一台服务器可以做哪些很酷的事情?
  9. Java 标准输入输出流(System.in,System.out)使用
  10. matlab定步长ode,[转载]matlab ode45 函数传自定义参数用法及定步长ode