• 简谈造成循环引用的原因以及处理办法


    前段时间写项目的时候我在每个block使用前我都加了一个__weak来修饰用@property描述的属性,项目写的差不多了回头来反思,总觉得这种写太麻烦了,回想起来,还是由于自己对于循环引用造成的原因理解不够透彻,才导致做了很多的无用功。

    废话不多说,上代码了 :

        /*

        // way 1  获取数据

        model = [[MoveModel alloc] init];

        model.successBlock = ^(id returnBlock) {

            NSArray *array = (NSArray *)returnBlock;

            _dataArray = array;

            [mainTableview reloadData];

        };

        [model getMoveData];

        */

     

        /*

        // way 2 获取数据

        [MoveModel GetDataSuccessBlock:^(id returnValues) {

            NSArray *array = (NSArray *)returnValues;

            _dataArray = array;

            [mainTableview reloadData];

        }];

         */

    这两种方式都是从别的类中获取数据的方法,way1采用的是属性block,way2采用的是参数block,而block内部的数据处理方式是一样的,但事实是way1造成了循环引用,而way2却没有。---不要问我怎么知道的,我就是知道~~

     

    block在iOS开发中视为对象因此生命周期会一直等到持有者的生命周期结束了才会结束另外一方面

    由于block的捕获变量的机制使得block的对象也可能被block持有从而造成循环引用造成内存泄露

     

    第一种情况就是这样的,block在控制器内部实现的,它的持有者是控制器本身,而在block内部又调用了_dataArray,它又持有了控制器。最终内存泄露了。

     

    解决办法: 1:声明 weakSelf

     

    typeof(self) __weak weakSelf = self

     

    block内部的_dataArray 换成weakSelf.dataArray

     

    但是这样又会产生另外一种特殊情况,就是在回调block的时候,block中的对象很有可能已经释放了,找不到对象会导致crash。这种情况比较少见,但是需要防范。

     

    2 在block内部在声明一个_strong 来修饰weakSelf 就行了。

     

    下面是afnetworking中的源码,既处理了循环引用的问题,又防范了突发情况的产生,处理方式值得借鉴:

    __weak __typeof(self)weakSelf = self;

        AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {

            __strong __typeof(weakSelf)strongSelf = weakSelf;

            strongSelf.networkReachabilityStatus = status;

            if (strongSelf.networkReachabilityStatusBlock) {

                strongSelf.networkReachabilityStatusBlock(status);

            }

        };

     

     

     

     

     

  • 相关阅读:
    Maven打包时过滤测试代码或指定特定的测试类(maven-surefire-plugin)
    Maven项目配置外部依赖(本地依赖)
    手把手教你创建「人物角色Persona」
    微服务与Docker介绍
    深入学习微框架:Spring Boot
    技术干货:我们的项目是如何技术选型的
    为什么选择Spring Boot作为微服务的入门级微框架
    Android Material Design 兼容库的使用详解
    Android 实现QQ、微信、新浪微博和百度第三方登录
    Android ijkplayer详解使用教程
  • 原文地址:https://www.cnblogs.com/110-913-1025/p/6993684.html
Copyright © 2020-2023  润新知