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

  1. Avoid strong reference cycles

    转自:http://masteringios.com/blog/2014/03/06/avoid-strong-reference-cycles/ With the introduction of A ...

  2. Resolving Strong Reference Cycles for Closures

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

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

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

  4. 避免在block中循环引用(Retain Cycle in Block)

    让我们长话短说.请参阅如下代码: - (IBAction)didTapUploadButton:(id)sender { NSString *clientID = @"YOUR_CLIENT ...

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

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

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

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

  7. strong & weak

    Here is a quick summary: A strong reference will keep the object it points to from being deallocated ...

  8. 《Programming with Objective-C》第八章 Working with Blocks

    Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDicti ...

  9. 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 ...

随机推荐

  1. jboss eap开启https协议

    1.使用 keytool -genkey -keystore chap8.keystore -storepass rmi+ssl -keypass rmi+ssl -keyalg RSA -alias ...

  2. redhat6.4上用apache建立os repos

    1.挂载OS介质文件 [root@server- Packages]# mkdir -p /media/dvd [root@server- Packages]# -20130130.0-Server- ...

  3. Python的平凡之路(7)

    一.面向对象高级语法部分   1.静态方法.类方法.属性方法                                                                       ...

  4. easyui js基础

    $(document).ready( function(){ initload(); });function initConfig(){ //数据列表 yzfymx=$("#tjdj&quo ...

  5. oracle查看当前用户权限

    查看用户和默认表空间的关系select username,default_tablespace from dba_users;--查看当前用户能访问的表select * from user_table ...

  6. Android应用增加计时器

    昨天写的Sudoku游戏需要增加计时器功能,使用Chronometer实现如下,由于Chronometer自己在调用stop之后后台的计时器还会继续增加,所以暂停功能需要额外实现: 在StartAct ...

  7. Android FM模块学习之四源码分析(3)

    接着看FM模块的其他几个次要的类的源码.这样来看FM上层的东西不是太多. 请看android\vendor\qcom\opensource\fm\fmapp2\src\com\caf\fmradio\ ...

  8. Android 中Thread,Handler,Loop学习

    1.先看一下最简单的进度条示例 EG: package com.sxz.android.thread; import java.util.concurrent.atomic.AtomicBoolean ...

  9. (实用篇)jQuery+PHP+MySQL实现二级联动下拉菜单

    二级联动下拉菜单选择应用在在很多地方,比如说省市下拉联动,商品大小类下拉选择联动.本文将通过实例讲解使用jQuery+PHP+MySQL来实现大小分类二级下拉联动效果. 先看下效果 大类:  前端技术 ...

  10. Java-->Gson序列化及反序列化

    --> 首先导入jar包,并添加到Build Path --> 需要User类:有属性.构造方法和setter.getter方法. --> Test 测试类: package com ...