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. register based 和 stack based虚拟机的区别

    其实其核心的差异,就是Dalvik 虚拟机架构是 register-based,与 Sun JDK 的 stack-based 不同,也就是架构上的差异.我先摘录几段网上可以找到的资料,重新整理和排版 ...

  2. Windows 通用应用尝试开发 “51单片机汇编”第二次更新总结

    一.前言 昨天更新了10天前上架到windows8.1平台和windowsphone平台的通用应用“51单片机汇编”,总要是添加了动态磁贴以及ListView的Groupstyle应用.下面主要主要复 ...

  3. SQLite存储类(数据类型)

    SQLite数据类型更普遍,采用动态类型系统. 说是数据类型,更像是存储类,如:INTEGER存储类就包含多种不同长度的整数数据类型 [INTEGER]带符号的整数类型 [REAL]浮点值,小数类型 ...

  4. 一步步调试解决iOS内存泄漏

      虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要. 这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄 ...

  5. c#用牛顿法计算根号下2的值

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. 去掉安卓中activity的标题栏

    去掉所有Activity界面的标题栏 修改AndroidManifest.xml 在application 标签中添加android:theme="@android:style/Theme. ...

  7. having和where的区别

    HAVING子句的使用. 例子: SELECT mob_belong_to,user_id,MAX(BIRTH_DATE) FROM user_base_info WHERE sign_in_date ...

  8. EF 自定义校验设置和捕获异常

    一.定义 public class MyItem: IValidatableObject { [Key] public long Id { get; set; } [Range(0, 100, Err ...

  9. 修改input的type属性

    在ff和chrome中是可以直接修改input的type属性的,但是在ie下面是不允许的. 用jquery 的attr方法去修改,在jquery1.8.3版本会直接抛出异常,但在1.9及以上版本就不再 ...

  10. Android中build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念区分 (转载)

    本文参考了谷歌开发者文档:http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#provisional 如果 ...