美文网首页iOS点点滴滴
__block 到底能不能防止循环引用呢

__block 到底能不能防止循环引用呢

作者: 柠檬草YF | 来源:发表于2018-01-27 11:40 被阅读146次

    如果不熟悉__block 和 block的应用和混合使用的请先移步上篇文章
    Block 拷贝或者捕获的是指针指向的内存地址,还是指针地址

    验证思想,分别使用 __block 和 __weak 来防止循环引用,看看对象会不会被释放

    第一个__block 例子

    #import "ViewController.h"
    
    @interface ViewController ()
    @property(nonatomic, copy)void(^block)(void);
    @property(nonatomic, strong)NSMutableArray *array;
    
    @end
    
    @implementation ViewController
    
    - (void)dealloc {
        NSLog(@"已经销毁");
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        __block ViewController *weakS = self;
        [self setBlock:^{
            NSLog(@"%@",weakS.array);
        }];
        self.block();
    }
    
    - (NSMutableArray *)array {
        if (_array == nil) {
            NSMutableArray *array = [NSMutableArray array];
            _array = array;
        }
        return _array;
    }
    
    

    第二个__weak 例子

    #import "ViewController.h"
    
    @interface ViewController ()
    @property(nonatomic, copy)void(^block)(void);
    @property(nonatomic, strong)NSMutableArray *array;
    
    @end
    
    @implementation ViewController
    
    - (void)dealloc {
        NSLog(@"已经销毁");
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        __weak ViewController *weakS = self;
        [self setBlock:^{
            NSLog(@"%@",weakS.array);
        }];
        self.block();
    }
    
    - (NSMutableArray *)array {
        if (_array == nil) {
            NSMutableArray *array = [NSMutableArray array];
            _array = array;
        }
        return _array;
    }
    

    把这个 ViewController 从 UINavigationController 中pop 出去,只有 __weak 修饰符的例子,打印了 已经销毁 的字样

    由此得出结论
    不管 block 捕获的是 指针的指针地址还是指针指向的内存地址,都会导致循环引用

    但是 循环应用的根本原因是 指针指向的内存导致的,如果我们把第一个__block例子的block的实现代码改一下

     __block ViewController *weakS = self;
     [self setBlock:^{
          NSLog(@"%@",weakS.array);
          weakS = nil;
     }];
    

    这样就可以避免了,但是第二次调用就读取不到array的值了,所以慎用!!!!!!!还是安安心心的用__weak 吧

    相关文章

      网友评论

        本文标题:__block 到底能不能防止循环引用呢

        本文链接:https://www.haomeiwen.com/subject/iclnaxtx.html