• Block的Retain Cycle的解决方法


    一个使用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”。

    (全文完)

  • 相关阅读:
    梦断代码阅读笔记-01
    构建之法阅读笔记03
    寒假学习013-突如其来的被忘了的作业
    寒假学习012-安卓登陆注册
    寒假学习011-安卓连网
    寒假学习010-安卓联网初试
    寒假学习009-云服务器的使用
    构建之法阅读笔记02
    寒假学习007-activity1
    寒假学习006-activity
  • 原文地址:https://www.cnblogs.com/zsw-1993/p/4879583.html
Copyright © 2020-2023  润新知