ios - 类方法中使用了block,如何避免循环引用?

 臻艾龙522_292 发布于 2022-10-26 13:39

代码如下,在netRequestCallBack的中的使用了vc,Xcode会告警提示: 可能导致循环引用。 请问如何消除?

+ (void)JumpToMe {
    dispatch_async(dispatch_get_main_queue(), ^{
    AUIViewController *vc = [[AUIViewController alloc] init];
    vc.mainModel.netRequestCallBack = ^(NSError *error){
        [[vc navigationController] pushViewController:vc animated:YES];
    };
    [vc.mainModel sendNetworking];
    });
}

尝试:

  1. vc使用修饰词 __block,但不能解决问题,而且__block修饰后,vc仍然是强引用的。

  2. vc使用修饰词__weak,确实消除了Xcode关于循环引用的告警。但netRequestCallBack 运行时,会发现vc已经被为nil
    我理解出现这种情况,是在类方法完成后,vc没有了持有者了,也是被释放了。

所以,请问有什么方法可以解决这个吗?

4 个回答
  • 先不说循环引用的问题

    [[vc navigationController] pushViewController:vc animated:YES];
    

    就这一句就有问题 vc没被push vc.navigationController会不为Nil? vc.navgationController 为nil的话 能push vc?

    2022-10-27 00:53 回答
  • 在你的block里用__strong __typeof(&*weaksSelf) strongSelf = weakSelf修饰

    2022-10-27 00:54 回答
  • block属性用copy,然后添加__strong __typeof(weaksSelf) strongSelf = weakSelf,不过你代码逻辑好怪

    2022-10-27 00:54 回答
  • 是否是循环引用与调用方法无关,只与引用关系有关。

    在你的例子中,引用环为 vc --> mainModel --> netRequestCallBack --> vc。("-->"表示引用关系)

    对象被释放的先决条件为该对象不被其他对象持有。而你的例子中vc被netRequestCallBack持有,所以不会被释放

    打破引用环的办法为使用__weak来声明被block捕获的变量。

    __weak AUIViewController *tmpVC = vc;
    vc.mainModel.netRequestCallBack = ^(NSError *error){
        [[tmpVC navigationController] pushViewController:vc animated:YES];
    };

    而对于vc被释放的问题,在于vc没有被别的对象持有。正确的解决办法应该是从当前navigaionController或别的vc栈中,找到该vc,然后对该vc进行操作。

    2022-10-27 00:54 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有