美文网首页
正确使用Block避免循环引用

正确使用Block避免循环引用

作者: airpoet | 来源:发表于2017-06-22 16:05 被阅读0次

    很多刚入门的宝宝面对block是心虚的,因为一提到block就会联想到:如果用的不好会出现循环引用引起内存泄漏问题,有时候想用但是自己又没有能发现循环引用的洞察力,所以在遇到block存在的地方,就使用__weak type(self) weakSelf = self;(被视为解决循环引用的必备良药) 这句话加上确实能保证不会出现循环引用的情况,但是并不是所有使用block的地方都会出现循环引用的,所以这个要具体问题具体对待,该用时那必须得用,没必要的时候,也就没有必要画蛇添足了。
    下面列举一处常见使用Block的例子,但是一般不会轻易出现循环引用,只要把关键点处理好就不会出现循环引用的问题。例子一:UIAlertController(弹出框视图控制器)想必大家再也熟悉不过了

    //点击按钮弹出提示框
    -(void)btnAction:(id)sender{ 
      NSLog(@"弹出框"); 
      UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"弹出框" message:@"" preferredStyle:UIAlertControllerStyleAlert]; 
    UIAlertAction *ok = [UIAlertAction actionWithTitle:@"确定" 
                                       style:UIAlertActionStyleDefault 
                                       handler:^(UIAlertAction * _Nonnull action) { 
                                        NSLog(@"Class****%@",[self class]); 
    //明目张胆在block中引用self,很多惧怕block中引用self会出现循环引用的宝宝会来这么一句:
          __weak type(self) weakSelf = self; 
    //接着NSLog(@"Class****%@",[weakSelf class]);然后心里才放心!其实这些都是画蛇添足,完全没有必要的! 
    }];
          UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 
          [alert addAction: ok];
          [alert addAction:cancel];
          [self presentViewController:alert animated:YES completion:nil];
    }
    

    这里把引用关系列一下就明白为什么安全无事了:


    引用关系图.png

    这里根本都没有造成闭环构成循环引用,前提是:你没有把UIAlertController对象或者UIAlertAction对象作为当前类的成员属性,一但self强引用了UIAlertController对象或者强引用了UIAlertAction对象,那么就构成闭环了,循环引用就会出现。一般编程中,没有必要把UIAlertController对象或者UIAlertAction对象作为当前视图控制器类的成员属性,去让self去持有它们的引用,一般都是像在本例中:在方法体中作为局部临时对象使用(self不会持有临时对象的引用),局部临时对象作用域只限制在方法体内部,也就是说这些临时对象的生命周期只限制在方法内部,一但方法执行完毕,这些临时创建的指针变量就会被置为nil
    ,如果指针被置为nil
    ,那么它原来所指临时对象就会被销毁。记住:局部指针变量,出了作用域就会被置为nil
    ,所指向的对象也会立即被系统释放。
    想测试到底会不会出现循环引用的有一个很简单的方法:就是在self.navigationController中pop掉当前控制器对象的时候(前提使用UINavigationController作为根视图控制器),看看当前视图控制器类中dealloc方法是否被执行,如果成功执行说明没有其他对象引用当前即将要pop掉的视图控制器,如果不执行,那么基本可以断定是由于代码中出现了循环引用,导致内存泄漏,无法得到释放的缘故。

    相关文章

      网友评论

          本文标题:正确使用Block避免循环引用

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