• Block循环引用解析




    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        Person *xiaozhang = [Person new];
        xiaozhang.FeedAnimalBlock = ^(BOOL hasFeed) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [xiaozhang feedOver];
            });
            
        };
    }

    xiaozhang引用feedBlock,block中引用xiaozhang,常见的循环引用。

    初级解决方案:在block外部,声明一个弱指针引用xiaozhang,若指针不会增加引用计数,打破了引用循环

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        Person *xiaozhang = [Person new];
        __weak typeof(xiaozhang)weakXiaozhang = xiaozhang;
        xiaozhang.FeedAnimalBlock = ^(BOOL hasFeed) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [weakXiaozhang feedOver];
            });
            
        };
    }

    循环引用的问题解决了,但是发现feedOver的方法并没有被调用

    分析:feedOver方法在2s之后执行,以为着viewDidLoad早已经执行完毕,而xiaozhang作为内部成员变量已经被释放,弱指针weakXiaozhang同时也被释放掉了,当然feedOver就不会调用

    思路:ViewDidLoad执行完毕之后,block外部xiaozhang被释放,要执行feedOver的方法,就要求在block中有一个指向xiaozhang的强指针,这样就不会被释放了,外部创建强引用的话又会出现循环引用

    解决方案:

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        Person *xiaozhang = [Person new];
        __weak typeof(xiaozhang)weakXiaozhang = xiaozhang;
        xiaozhang.FeedAnimalBlock = ^(BOOL hasFeed) {
            __strong typeof(weakXiaozhang)strongXiaozhang = weakXiaozhang;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [strongXiaozhang feedOver];
            });
        };
    }

    在block内部强引用person对象,生命周期和block的生命周期相同,当2s之后feedOver执行完,block生命周期结束,延时器和stronXiaozhang都会被销毁。

  • 相关阅读:
    奇技淫巧训练之一
    基于JS模块化现状谈谈选择ES6模块的原因
    vue-cli3项目搭建配置以及性能优化
    Umi + DvaJS
    ReactFragment用法介绍
    什么是纯函数
    10.25考试
    10.23考试
    线段树合并(雨天的尾巴 题解)
    10.21考试
  • 原文地址:https://www.cnblogs.com/xiaomaisgs/p/7510103.html
Copyright © 2020-2023  润新知