美文网首页
iOS block 简单循环引用,大环引用(为什么用 __wea

iOS block 简单循环引用,大环引用(为什么用 __wea

作者: 孙掌门 | 来源:发表于2019-12-16 21:20 被阅读0次

    ios block 简单循环引用,大环引用(为什么用 __weak 修饰可以打破循环引用,怎样做断环操作)

    分析下面的代码

    
     _arr = [NSMutableArray arrayWithObject:@"sunchengxiu"];
        _blk = ^ NSString *(void){
            return [NSString stringWithFormat:@"i am %@",_arr[0]];
        };
        _blk();
    
    

    上面的代码会发生循环引用,因为当前对象对 blk 进行了强引用,而_blk又对当前对象arr进行了强引用,所以就引起了循环引用

    解决方法

    _arr = [NSMutableArray arrayWithObject:@"sunchengxiu"];
        __weak NSArray *weakAArr = _arr;
        _blk = ^ NSString *(void){
            return [NSString stringWithFormat:@"i am %@",weakAArr[0]];
        };
        _blk();
    
    

    第一种解决方案是将当前arr 弱引用

    为什么用 __weak 就可以解决

    在之前的文章中,讲过截获变量,当block截获对象变量的时候,会连同他的修饰符一起截获,这里weakAArr是个对象,当block截获他的时候,会连同他的修饰符__weak一起截获到block的结构体中,所以,这样block就不会对self的arr产生强引用,这就解释了为什么用__weak修饰就可以打破循环引用。

    进阶(大环引用)

     self.name = @"sunchengxiu";
        __block ViewController *vc = self;
        _blk = ^ NSString *(void){
            return [NSString stringWithFormat:@"i am %@",vc.name];
        };
        _blk();
        
    
    

    在arc下会产生循环引用:

    当前对象引用了_blk,_blk又强引用了__block变量,而__block又是对原有对象的引用,所以就形成了

    当前对象 -> Block -> __Block 变量 -> 当前对象,这样一个大环引用.

    断环操作

     self.name = @"sunchengxiu";
        __block ViewController *vc = self;
        _blk = ^ NSString *(void){
            
            NSString *name = [NSString stringWithFormat:@"i am %@",vc.name];
            vc = nil;
            return name;
            
        };
        NSString *name = _blk();
        NSLog(@"%@",name);
    
    

    我们在其中加上这样一句,vc = nil; 就可以断环,但会有一个问题,如果不调用block,那么就一直会有引用,就不会释放。

    相关文章

      网友评论

          本文标题:iOS block 简单循环引用,大环引用(为什么用 __wea

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