MRC下block的循环引用

说明一下造成循环引用的场景,viewController持有某个view,view中持有block,block内部引用vc,造成的循环引用。在arc的环境下使用__weak即可解决问题,但是mrc中不能使用weak关键字(其实是可以在项目配置中设置的,但是考虑到老项目一般都没有开放mrc使用weak的配置,所以不使用weak),使用__block即可。

//view.h
@interface BlockView : UIView
@property(nonatomic, copy)void(^dismissCallback)(void);
@end

//view.m
@implementation BlockView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(jk_tapAction)];
        [self addGestureRecognizer:tap];
        
        [tap release]; tap = nil;
    }
    return self;
}

- (void)dealloc{
    [super dealloc];
}

- (void)jk_tapAction{
    if (self.dismissCallback) {
        self.dismissCallback();
    }
    self.backgroundColor = [UIColor blueColor];
}

@end

//vc.m
@interface BlockViewController ()
@property(nonatomic, retain)UILabel *titleLabel;
@end

@implementation BlockViewController{
    BlockView *_redView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    self.titleLabel.text = @"title";
    [self.view addSubview:self.titleLabel];
    
    __block typeof(self) weakSelf = self;
    _redView = [[BlockView alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
    _redView.backgroundColor = [UIColor redColor];
    _redView.dismissCallback = ^{
        //如果不使用weakSelf则无法进入dealloc
        weakSelf.titleLabel.text = @"changed";
    };
    [self.view addSubview:_redView];
}

- (void)dealloc{
    [_redView release]; _redView = nil;
    [_titleLabel release]; _titleLabel = nil;
    [super dealloc];
}

demo在这里https://gitee.com/Jack_1993/mrc_-playground
希望能够对在arc时代开始做iOS的大家有帮助:)

你可能感兴趣的:(MRC下block的循环引用)