1. <span style="background-color: rgb(248, 248, 248); font-family: 'PT Sans', Geogia, Baskerville, 'Hiragino Sans GB', serif; ">警告:Captureing ‘self’ strongly in this block is likely to lead to a retain cycle</span>

一个使用Block语法的实例变量,在引用另一个实例变量的时候,经常会引起retain cycle。这个问题在使用ASIHTTPRequest的block语法的时候会时不时的碰到。这个问题困扰了我这个小白很久。终于有一天,在 Advanced Mac OS X Programming上,看到了这个问题的解决方案。

先用代码描述一下症状:

  1. <span style="font-size:18px;">/* ViewController.h */
  2. #import <UIKit/UIKit.h>
  3. typedef void (^ABlock)(void); //定义一个简单的Block
  4. @interface ViewController : UIViewController {
  5. NSMutableArray *_items;
  6. ABlock _block;
  7. }
  8. @end
  9. /* ViewController.m */
  10. #import "ViewController.h"
  11. @implementation ViewController
  12. - (void)viewDidLoad
  13. {
  14. [super viewDidLoad];
  15. // Do any additional setup after loading the view, typically from a nib.
  16. _items = [[NSMutableArray alloc] init];
  17. _block = ^{
  18. [_items addObject:@"Hello!"]; //_block引用了_items,导致retain cycle。
  19. };
  20. }
  21. @end</span>

Xcode在编译以上程序的时候会给出一个警告:Captureing ‘self’ strongly in this block is likely to lead to a retain cycle。原因是_items实际上是self->items_block对象在创建的时候会被retain一次,因此会导致self也被retain一次。这样就形成了一个retain cycle。

解决方法就是,创建一个本地变量blockSelf,指向self,然后用结构体语法访问实例变量。代码如下:

  1. __block ViewController *blockSelf = self;
  2. _block = ^{
  3. [blockSelf->_items addObject:@"Hello!"];
  4. };

这么修改之后,blockSelf是本地变量,是弱引用,因此在_blockretain的时候,并不会增加retain count,所以retain cycle就解除了,Xcode也不再出现警告了,问题解决。

注:本文并非原创,详情请参阅Advanced Mac OS X Programming,第92页“Block Retain Cycles”。

n manual reference counting mode, __block id x; has the effect of not retaining x. In ARC mode, __block id x; defaults to retaining x (just like all other values). To get the manual reference counting mode behavior under ARC, you could use __unsafe_unretained __block id x;. As the name __unsafe_unretained implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use __weak (if you don’t need to support iOS 4 or OS X v10.6), or set the __block value to nil to break the retain cycle.

The following code fragment illustrates this issue using a pattern that is sometimes used in manual reference counting.

MyViewController *myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler =  ^(NSInteger result) {
   [myController dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:myController animated:YES completion:^{
   [myController release];
}];

As described, instead, you can use a __block qualifier and set the myController variable to nil in the completion handler:

MyViewController * __block myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler =  ^(NSInteger result) {
    [myController dismissViewControllerAnimated:YES completion:nil];
    myController = nil;
};

Alternatively, you can use a temporary __weak variable. The following example illustrates a simple implementation:

MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler =  ^(NSInteger result) {
    [weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};

For non-trivial cycles, however, you should use:

MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler =  ^(NSInteger result) {
    MyViewController *strongMyController = weakMyController;
    if (strongMyController) {
        // ...
        [strongMyController dismissViewControllerAnimated:YES completion:nil];
        // ...
    }
    else {
        // Probably nothing...
    }
};

[ios2]警告:Block的Retain Cycle的解决方法 【转】的更多相关文章

  1. Block的Retain Cycle的解决方法

    一个使用Block语法的实例变量,在引用另一个实例变量的时候,经常会引起retain cycle.这个问题在使ASIHTTPRequest的block语法的时候会时不时的碰到.这个问题困扰了我这个小白 ...

  2. elasticsearch报错expected <block end>, but found BlockMappingStart解决方法

    我用的是elasticsearch2.4.0,在修改完配置文件就出现类似格式 expected <block end>, but found BlockMappingStart...... ...

  3. 处理Block中的self问题(Capturing 'self' strongly in this block is likely to lead to a retain cycle)

    警告:ARC Retain Cycle Capturing 'self' strongly in this block is likely to lead to a retain cycle 代码: ...

  4. div之间有间隙以及img和div之间有间隙的原因及解决方法

    原因: div 中 存在 img标签,由于img标签的 display:inline-block 属性. display:inline-block布局的元素在chrome下会出现几像素的间隙,原因是因 ...

  5. Block代替delegate,尽量使用block,对于有大量的delegate方法才考虑使用protocol实现.

    Block代替delegate,尽量使用block,对于有大量的delegate方法才考虑使用protocol实现. 1.Block语法总结及示例如下:         //1.普通代码块方式bloc ...

  6. 关于找不到指定的模块,异常来自HRESULT:0x8007007E的解决方法

    上午从公司前辈那里拷贝到的ASP.NET代码,在自己机器上部署的时候发现问题,直接报错,找不到指定的模块,异常来自HRESULT:0x8007007E.并且一大堆警告. 在网上百度很多解决方法,归纳如 ...

  7. img和div之间有间隙的原因及解决方法

    div 中 存在 img标签,由于img标签的 display:inline-block 属性. #####display:inline-block布局的元素在chrome下会出现几像素的间隙,原因是 ...

  8. xcode arc 下使用 block警告 Capturing [an object] strongly in this block is likely to lead to a retain cycle” in ARC-enabled code

    xcode arc 下使用 block警告 Capturing [an object] strongly in this block is likely to lead to a retain cyc ...

  9. 在block函数中规避错误信息 "capturing self strongly in this block is likely to lead to a retain cycle”

    以形如 _fontValueChangedBlock = ^(){ [self.fontSmallButton addTarget:self action:@selector(btnFontSmall ...

随机推荐

  1. 全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org

    先给出官网地址:deflang.org 一句话简介:可扩展编程语言 Def 的目标是将 C++ 的高效抽象和 Lisp 的强大表现力融为一体. 你可以通过阅读 入门教程 .源码 或 测试用例 来简要或 ...

  2. .NET编程和SQL Server ——Sql Server 与CLR集成 (学习笔记整理-1)

    原文:.NET编程和SQL Server ——Sql Server 与CLR集成 (学习笔记整理-1) 一.SQL Server 为什么要与CLR集成 1. SQL Server 提供的存储过程.函数 ...

  3. C# dll 事件执行 js 回调函数

      C# dll 事件执行 js 回调函数   前言: 由于js 远程请求  XMLHttpRequest() 不支持多线程,所以用C# 写了个dll 多线程远程抓住供js调用. 最初代码为: C#代 ...

  4. error: C1083: 无法打开包括文件:“QDomDocument”“QAxObject”

    包含了头文件但是提示无法打开包括文件,是需要在项目的.pro里面手动加上一个变量 针对QAxObject是 QT       += axcontainer 针对QDomDocument是 QT     ...

  5. MVC文件上传与下载

    MVC文件上传与下载 MVC文件上传与下载 想想自己从毕业到工作也有一年多,以前公司的任务的比较重,项目中有的时候需要用到什么东西都去搜索一下,基础知识感觉还没有以前在学校中的好.最近开始写博客,真的 ...

  6. 【值得收藏】数据分析和可视化软件IDL的学习资料汇编【可免费下载】

    IDL学习教程 IDL 是一种数据分析和图像化应用程序及编程语言,最初在七十年代后期用于帮助科学家分析火星探险卫星发回的数据.此后,IDL得到广泛运用,使用者日众.IDL能使用户可以迅速且方便地运用此 ...

  7. C# 学习笔记2 C#底层的一些命令运行

    C#在DCP中运行的方法: 1.转到相应的目录 cd d:\1 2.输入csc /target:exe 2.cs 或者 csc /t:exe 2.cs 或者 csc 2.cs 在里边引用外部程序集的方 ...

  8. 状态机图statechart diagram

    [UML]UML系列——状态机图statechart diagram 系列文章 [UML]UML系列——用例图Use Case [UML]UML系列——用例图中的各种关系(include.extend ...

  9. [Usaco2008 Jan]Cow Contest奶牛的比赛[神奇的FLOYD]

    Description FJ的N(1 <= N <= 100)头奶牛们最近参加了场程序设计竞赛:).在赛场上,奶牛们按1..N依次编号.每头奶牛的编程能力不尽相同,并且没有哪两头奶牛的水平 ...

  10. D15

    T3: 树上的递归,很裸 T4:题目模型:二分染色问题 以及根据ccy大神指点,理解树形dp可以从 没有上司的舞会 聚会的快乐 这两题入手