避免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. HDOJ(HDU) 2060 Snooker(英语很重要。。。)

    Problem Description background: Philip likes to play the QQ game of Snooker when he wants a relax, t ...

  2. label标签的属性

    //label标签的属性 - (void)viewDidLoad { //初始化一个label1标签对象,初始化有很多方法,最原始的就是init,此处用带有frame的方法 UILabel *labe ...

  3. SpringMVC+SwfUpload进行多文件同时上传

    由于最近项目需要做一个多文件同时上传的功能,所以好好的看了一下各种上传工具,感觉uploadify和SwfUpload的功能都比较强大,并且使用起来也很方便.SWFUpload是一个flash和js相 ...

  4. 使用Cordova框架把Webapp封装成Hybrid App实践——Android篇

    公司没有IOS和没有安卓开发人员,前端后端都是需要自己玩前几天技术经理说有一个需求要把webapp封装成Hybrid App,现已完成.记录一下从中遇到的问题和需要用到的开发环境的配置 将Webapp ...

  5. motan源码分析一:服务发布及注册

    motan是新浪微博开源的服务治理框架,具体介绍请看:http://tech.sina.com.cn/i/2016-05-10/doc-ifxryhhh1869879.shtml. 本系列的文章将分析 ...

  6. IOS后台执行机制 与 动作

    当用户按下"Home"键或者系统启动另外一个应用时,前台foreground应用首先切换到Inactive状态,然后切换到Background状态.此转换将会导致先后调用应用代理的 ...

  7. Android四大组件——Service

    Service相关链接 Service初涉 Service进阶 Service精通 Service是Android系统中的一种组件,它跟Activity的级别差不多,但是它不能自己运行,只能后台运行, ...

  8. 命名空间引用问题 包括找不到ConfigurationManager 这个类

        因为SqlConnection类是属于 System.Data.SqlClient命名空间下的,     所以命名空间引用的时候需要加上 System.Data.SqlClient,代码如下: ...

  9. Android自定义属性、控件三步法

    第二步中layout-activity_main.xml 中自命名控件: xmlns:android="http://schemas.android.com/apk/res/android& ...

  10. 单向链表JAVA代码

        //单向链表类 publicclassLinkList{       //结点类     publicclassNode{         publicObject data;         ...