正确使用Block避免循环引用(一)

来源:互联网 发布:淘宝查看商品类目 编辑:程序博客网 时间:2024/06/13 10:10

很多刚入门的宝宝面对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];}

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

0 0
原创粉丝点击