Block的Retain Cycle的解决方法

来源:互联网 发布:暴躁的母亲知乎 编辑:程序博客网 时间:2024/05/17 07:52

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

先用代码描述一下症状:

1234567891011121314151617181920212223242526272829
#import typedef void (^ABlock)(void); //定义一个简单的Block@interface ViewController : UIViewController {    NSMutableArray *_items;    ABlock _block;}@end#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 islikely to lead to a retain cycle。原因是_items实际上是self->items_block对象在创建的时候会被retain一次,因此会导致self也被retain一次。这样就形成了一个retaincycle。

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

1234
__block ViewController *blockSelf = self;_block = ^{    [blockSelf->_items addObject:@"Hello!"];};

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

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

(全文完)

本文转自:http://cocoa.venj.me/blog/prevent-block-instance-retain-cycle/

0 0