strong reference cycle in block
However, because the reference is weak, the object that self points to could be deallocated while the
block is executing.
You can eliminate this risk by creating a strong local reference to self inside the block:
__weak BNREmployee *weakSelf = self; // a weak reference
myBlock = ^{
BNREmployee *innerSelf = weakSelf; // a block-local strong reference
NSLog(@"Employee: %@", innerSelf);
};
By creating the strong innerSelf reference, you have again created a strong reference cycle between
the block and the BNREmployee instance. But because the innerSelf reference is local to the scope of
the block, the strong reference cycle will only exist while the block is executing and will be broken
automatically when the block ends.
This is good programming practice whenever you write a block that must reference self.
If you use an instance variable directly within a block, the block will capture self instead of the
instance variable. This is because of a little-known nuance of instance variables. Consider this code
that accesses an instance variable directly:
__weak BNREmployee *weakSelf = self;
myBlock = ^{
BNREmployee *innerSelf = weakSelf; // a block-local strong reference
NSLog(@"Employee: %@", innerSelf);
NSLog(@"Employee ID: %d", _employeeID);
};
The compiler interprets the direct variable access like this:
__weak BNREmployee *weakSelf = self;
myBlock = ^{
BNREmployee *innerSelf = weakSelf; // a block-local strong reference
NSLog(@"Employee: %@", innerSelf);
NSLog(@"Employee ID: %d", self->_employeeID);
};
Does the -> syntax look familiar? It is the syntax for accessing the member of a struct on the heap. At
their deepest darkest cores, objects are actually structs.
Because the compiler reads _employeeID as self->_employeeID, self is unexpectedly captured by the
block. This will cause the same strong reference cycle that you avoided with the use of weakSelf and
innerSelf.
The fix? Don’t access instance variables directly. Use your accessors!
__weak BNREmployee *weakSelf = self;
myBlock = ^{
BNREmployee *innerSelf = weakSelf; // a block-local strong reference
NSLog(@"Employee: %@", innerSelf);
NSLog(@"Employee ID: %d", innerSelf.employeeID);
};
Now there is no direct use of self, so there is no unintentional strong reference cycle. Problem solved.
strong reference cycle in block的更多相关文章
- Avoid strong reference cycles
转自:http://masteringios.com/blog/2014/03/06/avoid-strong-reference-cycles/ With the introduction of A ...
- 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 三个引用类,引用类的 ...
- 避免在block中循环引用(Retain Cycle in Block)
让我们长话短说.请参阅如下代码: - (IBAction)didTapUploadButton:(id)sender { NSString *clientID = @"YOUR_CLIENT ...
- java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)
之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...
- Objective-C官方文档翻译 Block
版权声明:原创作品,谢绝转载!否则将追究法律责任. 一个Objective-c类定义了一个对象结合数据相关的行为.有时候,这使得他有意义的表达单个任务或者单元的行为.而不是集合的方法. blocks是 ...
- strong & weak
Here is a quick summary: A strong reference will keep the object it points to from being deallocated ...
- 《Programming with Objective-C》第八章 Working with Blocks
Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDicti ...
- Objective-C Programming The Big Nerd Ranch Guide 笔记 19-37
Properties are either atomic or nonatomic, The difference has to do with multithreading. atomic is t ...
随机推荐
- SPOJ GSS1 静态区间求解最大子段和
题目大意: 给定n个数,再给q个区间询问,希望在区间s,t中找到一段连续的子序列使其和最大 因为询问上万,节点数50000,明显是用线段树去做,这里很明显的区间更新,唯一写起来有点恶心的是询问 每一个 ...
- enmo_day_10
RMAN 创建备份集 : backup as backupset format ‘/backup/df_%d_%s_%p/bus’ tablespace hr_data; 创建镜像副本 :(备份慢,恢 ...
- JVM-字节码指令
Java虚拟机字节码指令 了解了class文件,我觉得就很有必要去了解一下JVM中的字节码指令,那样堆class文件以及JVM运行机制也后很大的帮助. Java虚拟机的指令由一个字节长度的,代表着某种 ...
- WCF开发指南之构建服务
一. 引言 Windows通讯基础(简称为WCF)是一种SDK,用于让你使用典型的CLR编程结构(例如用于发布和消费服务的类和接口等)来构建Windows面向服务的应用程序.WCF的编程模型是声明性的 ...
- JavaScript基础--DOM对象加强篇(十四)
1.document 对象 定义:document对象代表的整个html文档,因此可以去访问到文档中的各个对象(元素)document重要的函数 1.1 write 向文档输出文本或js代码 1.2 ...
- BackTrack5-r3安装前需要的准备及说明
一. 配置创建一个虚拟机,本教程用的是VMware-workstation-full-10.0.0,BT5-r3-GNOME-64镜像. 这里是BT5-r3-GNOME-64位种子:http://pa ...
- Error Handling
Use Exceptions Rather Than Return Codes Back in the distant past there were many languages that didn ...
- 传智播客JavaWeb day05-session、url重写
1.session是什么 1.1 session是一种会话技术 ps:还有一种是cookie 2.session的作用 2.1 服务器端会话范围内的数据共享 3.session的生命周期 3.1何时 ...
- C# Excel导入
两张表导入到一个DataGrid里面(题目表和答案表) 前台代码 <asp:Content ID="Content1" ContentPlaceHolderID=" ...
- H20的题——[noip2003]银河英雄传(并查集)
公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶集团派宇 ...