美文网首页
第一次掉进block循环引用的坑

第一次掉进block循环引用的坑

作者: Aloesshine | 来源:发表于2017-05-11 11:12 被阅读0次

    背景

    最近碰到一个需求,做视频播放的时候要求监控网络状态,若网络状态改变,比如没网到有网,自动刷新视频详情文案。

    于是我就在视频播放VC里面的viewDidLoad方法里面加入了这一段代码

    
    - (void)monitorNetWorkStart
    
    {
    
    // 1.获得网络监控的管理者
    
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    
    // 2.设置网络状态改变后的处理
    
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    
    // 当网络状态改变了, 就会调用这个block
    
    switch(status) {
    
    case AFNetworkReachabilityStatusUnknown:// 未知网络
    
    break;
    
    case AFNetworkReachabilityStatusNotReachable:// 没有网络(断网)
    
    break;
    
    case AFNetworkReachabilityStatusReachableViaWWAN:// 手机自带网络
    
    [self loadVideoDeatailDefault];  // 请求数据刷新界面
    
    break;
    
    case AFNetworkReachabilityStatusReachableViaWiFi:// WIFI
    
    [self loadVideoDeatailDefault];
    
    break;
    
    }
    
    }];
    
    // 3.开始监控
    
    [mgr startMonitoring];
    
    }
    
    

    本以为问题解决了,然而又出现了新的问题,退出视频页的时候,视频还在继续播放!!!

    这妥妥的VC没释放啊,因为之前从没实战过,所以查了一些资料找到了问题所在

    坑是怎么出现的

    AFNetworkReachabilityManager是一个单例,它持有了一个block属性,单例在进程死掉之前不会被释放,所以block的引用计数一直为1。

    在block中调用了 视频播放VC 的方法,所以block持有了 视频播放VC ,视频播放VC引用计数+1,并且因为block不会被释放,所以 视频播放VC 也不会被释放。

    在block中调用某个对象的方法,或者用了某个对象的属性,block就会持有该对象,而不是该对象的方法或属性

    怎么解决

    
    - (void)monitorNetWorkStart
    
    {
    
    // 1.获得网络监控的管理者
    
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    
    // 2.设置网络状态改变后的处理
    
    __weak __typeof__(self) weakSelf = self;
    
    [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    
    __typeof__(self) self = weakSelf;
    
    if (self.navigationController.topViewController != self) {
    
    return;
    
    }
    
    // 当网络状态改变了, 就会调用这个block
    
    switch(status) {
    
    case AFNetworkReachabilityStatusUnknown:// 未知网络
    
    break;
    
    case AFNetworkReachabilityStatusNotReachable:// 没有网络(断网)
    
    break;
    
    case AFNetworkReachabilityStatusReachableViaWWAN:// 手机自带网络
    
    [self loadVideoDeatailDefault];  // 请求数据刷新界面
    
    break;
    
    case AFNetworkReachabilityStatusReachableViaWiFi:// WIFI
    
    [self loadVideoDeatailDefault];
    
    break;
    
    }
    
    }];
    
    // 3.开始监控
    
    [mgr startMonitoring];
    
    }
    
    
    • 加__weak __修饰self可以使block不持有 视频播放VC,VC该释放的时候就释放

    • typeof(self) self = weakSelf; 这句可以防止 在执行block时self被释放造成crash

    后记

    小白一枚,如果哪里说的不对,请指正~

    相关文章

      网友评论

          本文标题:第一次掉进block循环引用的坑

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