Block的Retain Cycle的解决方法 (dealloc不掉用)

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

先用代码描述一下症状:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* ViewController.h */ 
#import <UIKit/UIKit.h>

typedef void (^ABlock)(void); //定义一个简单的Block

@interface ViewController : UIViewController {
    NSMutableArray *_items;
    ABlock _block;
}

@end

/* ViewController.m */ 

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _items = [[NSMutableArray alloc] init];
    _block = ^{
        [_items addObject:@"Hello!"]; //_block引用了_items,导致retain cycle。
    };
}

@end

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
2
3
4
__block ViewController *blockSelf = self;
_block = ^{
    [blockSelf->_items addObject:@"Hello!"];
};

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值