避免Block的循环引用

什么是循环引用,什么时候发生循环引用

1 循环引用就是当self 拥有一个block的时候,在block 又调用self的方法。形成你中有我,我中有你,谁都无法将谁释放的困局。

 self.myBlock = ^{
    [self doSomething];
  };
       +-----------+           +-----------+
       |    self   |           |   Block   |
  ---> |           | --------> |           |
       | retain 2  | <-------- | retain 1  |
       |           |           |           |
       +-----------+           +-----------+

又或者

ClassA* objA = [[[ClassA alloc] init] autorelease];
  objA.myBlock = ^{
    [self doSomething];
  };
  self.objA = objA;

  +-----------+           +-----------+           +-----------+
  |   self    |           |   objA    |           |   Block   |
  |           | --------> |           | --------> |           |
  | retain 1  |           | retain 1  |           | retain 1  |
  |           |           |           |           |           |
  +-----------+           +-----------+           +-----------+
       ^                                                |
       |                                                |
       +------------------------------------------------+

这是时官方的解释。
大体意思就是,例如self 有一个button ,而你又要 调用 button的某个东西设置.

[self.button  ^{ }]

到这步为止那就一点问题都没有,但是由于某些原因,你又要在这个block里调用
self.label.text = @"I am Label";
就变成这样了。

[self.button  ^{
      self.label.text = @"I am Label";
 }];

//这个时候就变成这样了。
  +-----------+           +-----------+           +-----------+
  |   self    |           |  button   |           |   Block   |
  |           | --------> |           | --------> |           |
  | retain 1  |           | retain 1  |           | retain 1  |
  |           |           |           |           |           |
  +-----------+           +-----------+           +-----------+
       ^                                                |
       |                                                |
       +------------------------------------------------+

大体理解就是这样,如果有偏差,欢迎指出。

解决方法

简而言之就一句话的事情:

__weak typeof (self) weakSelf = self;

例如上面那个例子,只要如下即可。

 __weak typeof (self) weakSelf = self;
[self.button  ^{
      weakSelf.label.text = @"I am Label";
 }];

//这个时候就变成这样了。
  +-----------+           +-----------+           +-----------+
  |   self    |           |  button   |           |   Block   |
  |           | --------> |           | --------> |           |
  | retain 1  |           | retain 1  |           | retain 1  |
  |           |           |           |           |           |
  +-----------+           +-----------+           +-----------+
       ^                                                |
       |                                                |
       + - - - - - - - - - - - - - - - - - - - - - - - -+
                               weak

避免Block的循环引用的更多相关文章

  1. 关于block的循环引用的问题

    在block的循环引用的问题上我们都知道如果在block内部修改外部的变量的时候,要加__block以防止循环引用的问题,但是如果block是当前对象的一个属性的时候,要修改当前对象的一个属性的时候就 ...

  2. iOS开发Block的介绍以及Block的循环引用问题

    1:block的循环引用问题最主要记住两点: 如果[block内部]使用[外部声明的强引用]访问[对象A], 那么[block内部]会自动产生一个[强引用]指向[对象A] 如果[block内部]使用[ ...

  3. block的循环引用

    什么是循环引用呢? 就是我引用你,你引用我,就会造成循环引用,双方都不会被销毁,导致内存泄漏. _block =  ^{ NSLog(@"%@", self); }; block会 ...

  4. block之---循环引用

    block内部引用外界对象的原则:block会对他内部所有的强指针进行强引用. 验证原理: 在主控制器中modal出ModalVC控制器,ModalVC中有强引用的block属性,在block内部使用 ...

  5. weakSelf 运用 strongSelf来解决block的循环引用

    SDWebImage 中有一段源码: #if SD_UIKIT Class UIApplicationClass = NSClassFromString(@"UIApplication&qu ...

  6. iOS - Block的循环引用内存泄漏问题探索

    循环引用的原因 众所周知,ARC下用block会产生循环引用的问题,造成泄露的原因是啥呢? 最简单的例子,如下面代码: [self.teacher requestData:^(NSData *data ...

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

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

  8. iOS开发小技巧--键盘处理以及解决block造成循环引用的小技巧

  9. block使用小结、在arc中使用block、如何防止循环引用

    引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...

随机推荐

  1. 常用sql语句及案例(oracle)

    目录 1)基本 2)数学函数 3)rownum 4)分页 5)时间处理 6)字符函数 7)to_number 8)聚合函数 9)学生选课 10)图书馆借阅 基本 --新建表: ) ) not null ...

  2. UVA10557- XYZZY(spfa+设置次数上限)

    题意:有N个房间,刚开始你位于1号房间,有100的能量值,你要到达N号房间,每两个房间之间有单向门相连接,你到达某个房间可以加上该房间的能量值, 如果你在未到达N号房间之前能量值耗尽,则死亡,否则胜利 ...

  3. des加密解密源码 C# key值问题

    公司协议安全需求.需要对传输内容做des.md5加密. 因为是新人.刚交给我这个任务的时候有点眩晕.就开始在网上找各种des加密的内容.因为不懂以为需要把原理也搞明白,最后误了时间.把自己也搞糊涂了. ...

  4. JS~字符串长度判断,超出进行自动截取(支持中文)

    今天一个小弟问我的问题,在文本框中输入字符,如果超出指定长度,就把它截取,要求中文等于两个字符的长度,我找一下资料,把这个功能实现了,下面是JS代码: <html> <script ...

  5. icinga 被动模式 nsca 安装

    本文假设读者已安装好icinga,此外nsca本身nagios插件,icinga/nagios都适用 一.编译安装nsca1.编译,拷贝文件tar -vxzf nsca-2.7.2.tar.gz./c ...

  6. 管道(Pipe)/createPipe

    BOOL CreatePipe(PHANDLE hReadPipe, // 指向读句柄的指针 PHANDLE hWritePipe, // 指向写句柄的指针 LPSECURITY_ATTRIBUTES ...

  7. XCode5/Apple LLVM 5.0下使用boost的方法

    Because Apple changes the compiler to llvm only in XCode5, so there are some compatible problems wit ...

  8. Cookie Version in J2EE

    Cookie Version in J2EE 原文章:http://villadora.me/2014/05/06/cookie-version/ 在处理Cookie的时候发现不能处理servlet ...

  9. 【iOS开发】emoji表情的输入思路

    1.自定义一个表情包类继承NSTextAttachment #import <UIKit/UIKit.h> /** 表情包的自定义类*/ @interface EmojiTextAttac ...

  10. Vitamio VideoView 示例

    VideoView 播放本地视频 /**  * 会根据视频尺寸自动缩放  * 自己对VideoView设置的宽高基本不起任何作用  */ public class VideoViewDemo exte ...