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 ...
随机推荐
- C# 6.0新特性(转载)
简介 VS 2015中已经包含C# 6.0. C#在发布不同版本时,C#总是会有新特性,比如C#3.0中出现LINQ,C#4.0中的动态特性,c#5.0中的异步操作等.. C# 6.0中与增加了不少新 ...
- 推荐!国外程序员整理的 C++ 资源大全
http://blog.jobbole.com/78901/ 关于 C++ 框架.库和资源的一些汇总列表,由 fffaraz 发起和维护. 内容包括:标准库.Web应用框架.人工智能.数据库.图片处理 ...
- Python12期培训班-day1-三级菜单代码分享
#!/usr/bin/env python3 import sys import os zonecode = { '广东省': {'广州市':['越秀区','海珠区','荔湾区','天河区'], '深 ...
- jquery 获取浏览器可视窗口大小,滚动条高度
alert($(window).height()); //浏览器时下窗口可视区域高度 alert($(document).height()); //浏览器时下窗口文档的高度 alert($(docum ...
- 20160621-BAPI 更改外向DN&更改拣配
参考代码转自:http://blog.sina.com.cn/s/blog_4c66402b01012lgr.html 感谢. 测试一把,再做总结. 1.更改外向交货单: 2.更改内向交货单. htt ...
- document的一点点
var str = "hello world" document.write(str.length)输出字符串长度 12 给string 添加样式 <p>Big: ...
- 16年青岛网络赛 1001 I Count Two Three
题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1001&cid=723 I Count Two ThreeTi ...
- 【 D3.js 入门系列 --- 2.1 】 关于如何选择,插入,删除元素
在D3.js中,选择元素的函数有两个:select 和 selectAll . 先说明一下它们的区别: select 是选择所有指定元素的第一个 selectAll 是选择指定元素的全部(以用于后面同 ...
- 队列的链式实现(C语言)
/* Queue.h */ #ifndef QUEUE_H_INCLUDED #define QUEUE_H_INCLUDED #include <stdio.h> #include &l ...
- WebJars 进行 css js 资源文件管理
WebJars是将这些通用的Web前端资源打包成Java的Jar包,然后借助Maven工具对其管理,保证这些Web资源版本唯一性,升级也比较容易.关于webjars资源,有一个专门的网站http:// ...