zoukankan      html  css  js  c++  java
  • 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都会被销毁。

  • 相关阅读:
    android:sharedUserId
    SystemProperties cannot be resolved错误
    Mybatis(二)|搭建mybatis环境之注解版-简单搭配
    Eclipse构建Maven的SpringMVC项目
    IDEA新手使用教程(详解)(经典)
    IntelliJ IDEA 教程
    用注解的方式实现Mybatis插入数据时返回自增的主键Id
    eclipse使用git提交项目
    eclipse中使用自带git的常用操作
    myeclipse10.7安装git插件
  • 原文地址:https://www.cnblogs.com/xiaomaisgs/p/7510103.html
Copyright © 2011-2022 走看看