文档章节

内存的循环引用

吾名蔚
 吾名蔚
发布于 2017/02/12 21:59
字数 751
阅读 46
收藏 1

内存的循环引用

在 ARC,开发者将会定义一个变量为“strong”或“weak”。一个 weak 弱引用无法 retain 对象,而 strong 引用会 retain 这个对象,并将其引用计数加一。

循环引用就是指两个对象互相retain对方,通过OBJC的release是无法销毁这两个对象的

更严重的是,如果几个对象间接相互引用,比如a<-b b<-c  c<-a 那么a、b、c都无法通过release释放

循环引用的场景

一、定时器NSTimer

二、block的使用

三、代理delegate

四、父子对象关系(swift)

定时器:

我们在使用NSTimer时经常会作为一个类的属性使用

而NSTimer在初始化的时候回指定self为target.这就造成了self—>NSTimer-->self的循环引用的情况。另外在NSTimer一致处于validata状态时其引用计数器一直是大于0的

解决办法:在不使用定时器以后要调用invalidata移除定时器。

block的使用

block在引用外部的变量是,会对外部变量进行copy操作。在(ARC)模式下会对变量进行强引用,(MRC)模式下变量retainCount加1。当一个类把block作为成员变量时,在block内部使用了这个类本身。造成self—>block-->self或者self-->block-->类的成员变量循环引用的情况。

解决办法:在MRC模式下,在给block赋值时在外部用__blockmySelf = self;用__block修饰使用到的类。

在ARC模式下,用__weak修饰 

代理:

代理协议也是一个典型的场景,需要你使用弱引用来避免循环引用。将代理声明为 weak 是一个即好又安全的做法

父子对象关系

父子对象关系是一个循环引用的典型案例,不幸的是,它也是唯一一个存在于苹果文档中的案例。典型的解决方法就是,在子类定义一个指向父类的变量,声明为 weak 弱引用,从而避免循环引用。

在 swift 中子类指向父对象的变量是一个弱引用,这就迫使我们将该弱引用定义为 optional 类型。如果不使用 optional 可以有另一种做法,将指向父对象的变量声明为“无主引用(unowned)”(表明我们不持有该对象,也不对其进行内存管理)。然而在这种情况下,我们必须非常小心,确保只要还有子对象指向它,父对象不变成 nil,否则会直接闪退。

调试:

使用 Instruments 调试循环引用

XCode 自带了一个很强大的工具 Instruments,用于检测和定位循环引用。一旦你的 app 开发结束,即将提交到 Apple Store,先分析你的 app 是一个好的习惯。Instruments 有很多组件,可以用来分析 app 的不同方面,但是我们现在关心的是 Leak 选项。

© 著作权归作者所有

共有 人打赏支持
吾名蔚
粉丝 1
博文 7
码字总数 3455
作品 0
浦东
程序员
iOS中Block循环引用刨根问底

序言 Blocks是苹果出的轻量型回调方式,使用起来既简洁,又方便。不过就是会产生一个问题:循环引用。进而会导致内存释放不了,造成内存泄漏。那到底怎么样才会产生循环引用呢?如何解决呢? ...

FlyOceanFish
05/07
0
0
iOS 面试题~避免循环引用~解决方法

//联系人:石虎QQ:1224614774昵称:嗡嘛呢叭咪哄 一、概念: 循环引用:指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。 其实循环引用...

石虎132
2017/12/22
0
0
JavaScript 的垃圾回收与内存泄露

JavaScript采用垃圾自动回收机制,运行时环境会自动清理不再使用的内存,因此javascript无需像C++等语言一样手动释放无用内存。 在这之前先说一下垃圾回收的两种方式:引用计数与标记清除。 ...

smalldragonluo
2014/06/16
0
0
ios-常见的循环引用

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

余成海
2016/04/12
1K
0
ARC 模式下的循环引用引起内存泄漏

自从iOS 5时代自动引用计数(Automatic Reference Counting)技术发布,Cocoa工程师们才扔下了内存管理的包袱,从此在Objective-C修行道路上的一座大山被削平。然而,即使ARC很强大,我们日...

秋刀生鱼片
2016/09/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

分布式缓存架构设计

零、 题记 在高并发场景下,需要通过缓存来减少数据库的压力,使得大量的访问进来能够命中缓存,只有少量的需要到数据库层。由于缓存基于内存,可支持的并发量远远大于基于硬盘的数据库。所以...

Ala6
21分钟前
2
0
简单工厂模式

public abstract class Operation { private double numberA = 0; private double numberB = 0; public double getNumberA() { return numberA; } ......

NinjaFrog
23分钟前
1
0
git(一) 基本操作(branch、tag、冲突)

layout: blog istop: true title: "git基本操作(branch、tag、冲突)" date: 2018-09-11 category: 版本控制 tags: - 版本控制 撤销操作 修改最后一次提交 解释:修改上次提交。可以修改内容...

开心的哈士奇
26分钟前
1
0
Vue中路由管理器Vue Router使用方式(二)-推荐

一、Vue中使用Vue Router简单方式使用 vue add xxx命令添加插件 使用步骤,本人假设已经安装好了Vue CLI工具,了解更多参考:VSCode 搭建Vue开发环境之Vue CLI 1.创建项目 vue create hello...

tianma3798
38分钟前
1
0
设计模式(十六)[结构模式] 装饰模式(Decorator)

1.什么是装饰模式? 装饰模式又名包装模式。装饰模式以对客户端透明的方式扩展对象功能,是继承关系的一个替代方案。 2.模式的类图 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收...

1527
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部