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

很多刚入门的宝宝面对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掉的视图控制器,如果不执行,那么基本可以断定是由于代码中出现了循环引用,导致内存泄漏,无法得到释放的缘故。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值