Block内使用的外部weak变量,如何防止被释放

2018-03-14  本文已影响0人  _码奴

block引用计数基本概述:
在block被销毁前,block会释放所有内部对象的引用计数,但是如果block被作为属性使用copy关键字,被复制到堆内存中,那么在block的引用计数变成0之前,就无法被销毁,那么内部使用的对象的引用计数+1,就无法释放,所以如果不对self使用weak关键字的话,在block中直接使用self,就会造成循环引用。

这里重点说一下Block内使用的外部weak变量,如何防止被释放问题

#import "SecondViewController.h"

@interface SecondViewController ()

@property (nonatomic,copy) void(^block)(void);

@end

@implementation SecondViewController

-(void)dealloc {
    NSLog(@"dealloc");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor];
    [self makeView];
}

-(void)makeView {
    
    UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn setTitle:@"go back" forState:UIControlStateNormal];
    btn.frame = CGRectMake(10, 100, 200, 50);
    [self.view addSubview:btn];
    btn.backgroundColor = [UIColor blueColor];
    [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];

    self.block = [self getBlock];
    
}

-(void(^)(void))getBlock {
    
    __weak typeof(self) weakSelf = self;
    
    NSLog(@"mode1 = %@",self);
    //如果不使用weak,直接在block块中使用self的话,引用计数+1,block执行结束的时候不能自动减去1
    void(^block)(void) = ^{
        //这里使用__strong关键字加1,会在block执行结束时自动减去
        __strong typeof(weakSelf) ss = weakSelf;
        //这里推迟3秒执行
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"mod = %@",ss);
        });
    };
    
    return block;
}

-(void)btnAction:(UIButton *)btn {
    self.block();
    [self.navigationController popViewControllerAnimated:YES];
}
上一篇下一篇

猜你喜欢

热点阅读