Avoid strong reference cycles
转自:http://masteringios.com/blog/2014/03/06/avoid-strong-reference-cycles/
With the introduction of ARC, memory management became easier. However, even though you don’t have to worry about when to retain and release, there are still a few rules you need to know in order to avoid memory problems. In this post we’re going to talk about strong reference cycles.
What exactly is a strong reference cycle? Let’s assume that you have two objects, object A and object B. If object A holds a strong reference to object B and object B has a strong reference to object A then we have a strong reference cycle. We’re going to talk about two very common situations where you need to be careful about reference cycles: blocks and delegates.
1. Delegates
Delegation is a commonly used pattern in Objective C. In this case one object acts on behalf of or in coordination with another object. The delegating object keeps a reference to the other object (the delegate) and at the appropriate time it sends a message to it. The delegate is the able to respond by updating the appearance or the state of the application.
One example from the API is the UITableView and its delegate. In this example the table view has a reference to its delegate and the delegate has a reference back to the table view. This means that each one is keeping the other alive so even if there are no other objects pointing to the delegate or the table view, the memory doesn’t get deallocated.
Let’s consider a custom example:
#import @class ClassA; @protocol ClassADelegate -(void)classA:(ClassA *)classAObject didSomething:(NSString *)something; @end @interface ClassA : NSObject @property (nonatomic, strong) id delegate; @end
This will generate a retain cycle in an ARC world. To prevent this all we need to do is change the reference to our delegate to be weak:
@property (nonatomic, weak) id delegate;
A weak reference does not imply ownership or responsibility between two objects and does not keep an object alive. If there are no other objects pointing to the delegate and the delegating object, then first the delegate will get deallocated and so it will release its strong reference to the delegating object. With nobody pointing to it the delegating object will also get released.
2. Blocks
Blocks are chunks of code, similar to C functions, but in addition to executable code they may contain variable bindings to stack or heap memory. A block can therefore maintain a set of data that it can use to impact behaviour when executed. Because blocks maintain the data needed for execution of the code, they are particularly useful as callbacks.
Blocks are Objective C objects, however there are some memory management rules that only applies to blocks, no other Objective C objects.
Blocks maintain strong references to any captured objects, including self, so it’s very easy to end up with a strong reference cycle. If a class has a property for a block like this:
@property (copy) void (^block)(void);
And in its implementation you have a method like this:
- (void)methodA {
self.block = ^{
[self methodB];
};
}
then you’ve got yourself a strong reference cycle: the object (self) has a strong reference to the block and the block just captured a strong reference to self.
Note: For block properties its a good practice to use copy, because a block needs to be copied to keep track of its captured state outside of the original scope.
In order to avoid this strong reference cycle we need to use weak references again. This is how the code would look like:
- (void)methodA {
ClassB * __weak weakSelf = self;
self.block = ^{
[weakSelf methodB];
};
}
By capturing the weak reference to self, the block won’t maintain a strong relationship to the object. If the object is deallocated before the block is called the weakSelf pointer will simply be set to nil. While this is great because there won’t be a memory problem, if the pointer is nil then our method inside the block won’t get called and so the block won’t have the expected behaviour. To avoid this, we’re going to alter our example a bit further:
- (void)methodA {
__weak ClassB *weakSelf = self;
self.block = ^{
__strong ClassB *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf methodB];
}
};
}
We are creating a strong self reference inside the block. This reference will belong to the block and it will be alive for as long as the block is. It won’t prevent the self object for being deallocated so we are still avoiding the strong reference cycle.
Not all strong reference cycles are as easy to see as the one in my example so you might consider using a weak reference whenever your block code gets a bit more complicated.
These are two common patterns where strong reference cycles can appear. As seen, it’s very easy to break these cycles with weak reference as long as you can correctly identify them. You need to be mindful of memory management even if ARC made is easier for all of us.
Avoid strong reference cycles的更多相关文章
- Resolving Strong Reference Cycles for Closures
You resolve a strong reference cycle between a closure and a class instance by defining a capture li ...
- Java中引用类 strong reference .SoftReference 、 WeakReference 和 PhantomReference的区别
当在 Java 2 平台中首次引入 java.lang.ref 包,其中包含 SoftReference . WeakReference 和 PhantomReference 三个引用类,引用类的 ...
- strong reference cycle in block
However, because the reference is weak, the object that self points to could be deallocated while th ...
- java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)
之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...
- ARC(Automatic Reference Counting )技术概述
此文章由Tom翻译,首发于csdn的blog 转自:http://blog.csdn.net/nicktang/article/details/6792972 Automatic Reference ...
- Objective-C官方文档翻译 Block
版权声明:原创作品,谢绝转载!否则将追究法律责任. 一个Objective-c类定义了一个对象结合数据相关的行为.有时候,这使得他有意义的表达单个任务或者单元的行为.而不是集合的方法. blocks是 ...
- ARC下需要注意的内存管理
ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu) 之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也 ...
- iPhone之IOS5内存管理(ARC技术概述)
ARC(Automatic Reference Counting )技术概述 此文章由Tom翻译,首发于csdn的blog,任何人都可以转发,但是请保留原始链接和翻译者得名字.多谢! Automati ...
- ARC下需要注意的内存问题
之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也有好多人反馈看不太懂,这次谈谈iOS中ARC的一些使用注意事项,相信做iOS开发的不会对ARC陌生啦.这里不是谈ARC的使用,只是介绍下 ...
随机推荐
- Android 之 AndroidManifest.xml 详解(一)
当Android启动一个应用程序组件之前,它必须知道哪些个组件是存在的,所以开发人员在开发过程中,必须将应用程序中出现的组件一一在AndroidManifest.xml文件中" 声明 &qu ...
- JPA中的一对多双向关联与级联操作
学习Spring有两周时间了 , 个人觉得服务端主要实现的是数据关系的维护和数据结构的制定 , 以及由业务需求产生的CRUD , 只要保证对前端提供的接口稳定高效响应 , 具体的前端实现完全不关心. ...
- interllij13新建maven web工程
1. 打开intellij,左边的可以别管它(历史) ②选择create new project(新建一个项目),选择Maven,并选择一个web模板,然后next. 3. 给自己的项目取名,grou ...
- jdbc第三天
事务 什么是事务? 转账: 1. 给张三账户减1000元 2. 给李四账户加1000元 当给张三账户减1000元后,抛出了异常!这会怎么样呢?我相信从此之后,张三再也不敢转账了. 使用事务就可以处理这 ...
- MySQL的各种SHOW
. SHOW语法 13.5.4.1. SHOW CHARACTER SET语法 13.5.4.2. SHOW COLLATION语法 13.5.4.3. SHOW COLUMNS语法 13.5.4.4 ...
- 1z0-052 q209_4
4: You have two tables with referential integrity enforced between them. You need to insert data to ...
- 【mysql+RBAC】RBAC权限处理(转载:http://www.cnblogs.com/xiaoxi/p/5889486.html 平凡希)
1.这里我只讲核心,mysql查询语句:FIND_IN_SET(str,strlist) 2.具体教程可以参考[童攀老师的RBAC],很清晰,赞一个. 3.详解:mysql的find_in_set 首 ...
- 关于iOS Category实现添加属性及成员变量
iOS分类: 很多说法是只能添加方法,而不能添加成员变量或属性. 有些人可能知道,这种说法是不严谨的,并不是绝对不能添加变量. 解释如下: 我们知道在一个类中用@property声明属性,编译器会自动 ...
- IE浏览器SCRIPT5拒绝访问,谷歌浏览器XMLHttpRequest can't load file:/......
一.背景 在测试ajax时,写了一个ajax.html,目的是访问example.txt中的文本,写好后,右键该html选择在浏览器中打开,浏览器页面上无内容.调出调试窗口: IE浏览器:SCRIPT ...
- HTML:调用静态页面html 的几种方法
今天做办公用品管理系统时,发现需要用到在一个静态页面html 中调用多个静态页面html的内容.查找资料总结了以下一些方法: 一.iframe引入的方法 代码如下: <!-- 部门--> ...