转自: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的更多相关文章

  1. Resolving Strong Reference Cycles for Closures

    You resolve a strong reference cycle between a closure and a class instance by defining a capture li ...

  2. Java中引用类 strong reference .SoftReference 、 WeakReference 和 PhantomReference的区别

      当在 Java 2 平台中首次引入 java.lang.ref 包,其中包含 SoftReference . WeakReference 和 PhantomReference 三个引用类,引用类的 ...

  3. strong reference cycle in block

    However, because the reference is weak, the object that self points to could be deallocated while th ...

  4. java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)

    之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...

  5. ARC(Automatic Reference Counting )技术概述

    此文章由Tom翻译,首发于csdn的blog 转自:http://blog.csdn.net/nicktang/article/details/6792972 Automatic Reference ...

  6. Objective-C官方文档翻译 Block

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 一个Objective-c类定义了一个对象结合数据相关的行为.有时候,这使得他有意义的表达单个任务或者单元的行为.而不是集合的方法. blocks是 ...

  7. ARC下需要注意的内存管理

    ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu)    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也 ...

  8. iPhone之IOS5内存管理(ARC技术概述)

    ARC(Automatic Reference Counting )技术概述 此文章由Tom翻译,首发于csdn的blog,任何人都可以转发,但是请保留原始链接和翻译者得名字.多谢! Automati ...

  9. ARC下需要注意的内存问题

    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也有好多人反馈看不太懂,这次谈谈iOS中ARC的一些使用注意事项,相信做iOS开发的不会对ARC陌生啦.这里不是谈ARC的使用,只是介绍下 ...

随机推荐

  1. 关于SQL 行转列的办法

    公司实施小姑娘要我写一个SQL给她 需求如下: 现在有表A,字段 id code parentid backres,现数据如下 id code parentid backres 1 A 5 2 B 5 ...

  2. JavaScript 之 parseInt

    首先还是从很热门的实例parseInt("09")==0说起. parseInt(numString, [radix])这个函数后面如果不跟第2个参数来表示进制的话,默认是10进制 ...

  3. Nor Flash启动和Nand Flash启动时Stepping stone都在哪?

    当从Norflash启动时,Steppingstone被映射到地址 0x4000 0000 至 0x4000 0FFF: 当从Nandflash启动时,Steppingstone被映射到地址 0x00 ...

  4. 算法笔记_194:历届试题 翻硬币(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 小明正在玩一个“翻硬币”的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情 ...

  5. 算法笔记_109:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科B组部分习题)试题解答

    目录 1 马虎的算式 2 黄金连分数 3 有理数类 4 幸运数 5 连号区间数   前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 马虎的算式 标题: 马虎的算式 小明 ...

  6. 安装 启动sshd服务:

    .先确认是否已安装ssh服务: [root@localhost ~]# rpm -qa | grep openssh-server openssh-server-.3p1-.fc12.i686 (这行 ...

  7. Android 如何将Canvas上绘制的内容保存成本地图片(转)

    效果如下图所示 保存在sd卡上的文件为 手机上显示效果为: 1>>在Manifest文件中增加相应权限 <!-- 在SDCard中创建与删除文件权限 --> <uses- ...

  8. 基于jquery ui修改的不依赖第三方的背景透明的弹出div

    效果图: 代码: <!doctype html> <html> <head> <meta charset="utf-8"> < ...

  9. 保护HTTP的安全

    #如果没有严格的限制访问的权限,公司放在服务器上的重要文档就存在隐患,web需要有一些安全的http形式: #安全方法: #基本认证.摘要认证.报文完整性检查都是一些轻量级的方法,但还不够强大,下面介 ...

  10. 27、ArrayList和LinkedList的区别

    在Java的List类型集合中,ArrayList和LinkedList大概是最常用到的2个了,细看了一下它们的实现,发现区别还是很大的,这里简单的列一下个人比较关心的区别. 类声明 ArrayLis ...