• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 即使在 Reactivecocoa 中加强,self 也会变为 nil

[复制链接]
菜鸟教程小白 发表于 2022-12-13 14:47:33 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我猜代码本身解释了一切,所以看看下面的代码。

-(RACSignal *)bossMethod {
    @weakify(self)
    return [[[self method1] flattenMap:^RACStream *(id value) {
        @strongify(self)
        return [self method2];
    }] flattenMap:^RACStream *(id value) {
        @strongify(self)
        return [self method3];
    }];
}

基本上,我将信号链接起来以逐步执行多种方法。但是方法 3 根本没有被调用。所以我坚持下去,发现 self 在 [self method3] 即将被调用的时候变成了 nil。它是怎么发生的?为什么 @strongify(self) 在这种情况下不起作用?如有任何建议,我将不胜感激。



Best Answer-推荐答案


self 可能在第一个和第二个 flattenMap block 执行之间被设置为 nil(因为最后一个 strong 对作为 self 的对象的引用已被删除)。

一般 @strongify 不保证变量不为零。它只保证它不会突然设置为 nil inside 范围(在你的情况下,在 flattenMap block 内)。

假设您没有使用过 @strongify 并且有以下代码:

  @weakify(self)
    return [[self method1] flattenMap:^RACStream *(id value) {
        [self doSomethingPossiblyLong];  //1
        return [self method2]; //2
    }];

现在,在传递给 flattenMap 的 block 中,您执行两个操作。第一个(1)做一些(可能很长)计算。第二个 (2) 做的事情取决于 (1) 的结果。而且您处理的是多线程代码,因此在这些计算期间(或之后)另一个线程可以启动。

在第二个线程中,可能会删除对您的 self 对象的最后一个强引用。例如,它可能是 UI(主)线程,它可以关闭拥有该对象的 View Controller 。然后 ARC 将完成它的工作,将对这个对象的所有弱引用变为 nil

现在执行回到 flattenMap block ,到这一行:

return [self method2]; //2

但是self变成了nil。之前所有的计算都是徒劳的,太糟糕了。

在这种情况下,使用 @strongify 是有意义的。因为您要确保在 flattenMapblock 中的代码开始执行后,对 self 的引用(或包装在 @strongify 中的其他变量宏) 直到 block 的最后才为 nil

请注意,在您发布的代码中,flattenMap 内只有单个方法调用,因此您并没有真正从 @strongify 中受益。但是使用它可能仍然是一个好习惯,因此当您在 block 内添加更多调用 self 的方法时,您不会忘记它。

关于ios - 即使在 Reactivecocoa 中加强,self 也会变为 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35557724/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap