【问题标题】:Differences between weak and unsafe_unretainedweak 和 unsafe_unretained 的区别
【发布时间】:2012-06-20 14:29:57
【问题描述】:

所以我有一个支持 iOS 4 的项目,所以我所有的 IBOutlets 都是__unsafe_unretained,即使是在 nib 中但在控制器主视图之外的 IBOutlets(同一个 nib 中的单独视图)并且都运行良好。

时间到了,现在客户只想支持 iOS 5,所以我们的团队将所有 __unsafe_unretained IBOutlets 更改为 __weak IBOutlets,但现在不在主视图内的 IBOutlets 设置为 nil ( viewdidload) 除外,因此我们以后无法添加它们。

如果我考虑一下,这是有道理的,因为如果没有视图(主视图)保留那些 IBOutlets,它们应该被释放并归零(我不知道这是否是正确的词),所以解决方案是删除来自那些 IBOutlets 的 __weak

但是对我来说没有意义的是为什么 unsafe_unretainedweak 之间的行为不同,在我的脑海中 unsafe_unretained 应该被释放,当应用程序尝试访问它们时,它们应该指向一个无效的引用,然后应用程序应该崩溃。

我认为 unsafe__unretained 与 weak 相同,但没有归零。

我错过了什么吗?

谢谢。

【问题讨论】:

  • 你是对的。 unsafe_unretained 不为零引用。

标签: objective-c ios5 memory-management ios4


【解决方案1】:

我认为 unsafe__unretained 与 weak 相同,但没有归零。

是的,是的。

当 Cocoa 加载 nib 时,它会创建所有自动释放的对象,因此在调用 viewDidLoad 时它们仍然存在。但是,自动释放池的生命周期在控制权返回到运行循环时结束。此时,所有不属于任何东西的对象都将消失,因此任何弱出口都将在此时归零。

对于大多数商店来说,这不是问题,因为 NIB 中的对象通常已经由某物拥有。因此,例如,视图中的按钮归其父视图所有。因此,拥有指向该按钮的强大出口是矫枉过正或更糟的可能导致保留周期。

顶级对象显然没有父视图来拥有它们,因此它们需要由其他东西拥有,例如控制器或“文件的所有者”。如果你发现东西消失了,你需要在 File 的所有者中为它创建一个强大的 IBOutlet。

更多详情,请参阅Apple's docs

【讨论】:

  • 这很有意义,我完全意识到这一点,但我的问题是为什么当我使用 unsafe_unretained 时,那些 IBOutlets 永远不会被释放,我可以在任何时候(及时)我想要的时候使用它们?
  • @Ecarrion,在我看来,直到内存块未被覆盖/覆盖为止。当它被覆盖时,应用程序会获得错误的访问权限。
【解决方案2】:

对于遇到此问题的未来搜索者,我认为 CRD 的Stackoverflow answer 可以解释类似问题。即使对象已被释放,不安全的未保留指针(包含实际对象数据)所引用的内存也不一定会归零,因此在实际重用/修改/归零该内存之前,事情可能会正常运行。

【讨论】:

    【解决方案3】:

    你是对的,当试图通过你陈旧的 __unsafe_unretained 引用访问已释放的对象时,应用程序会崩溃。

    它没有被引用的原因很可能是因为这些对象正被您的应用程序的某些其他部分以强引用方式引用。

    尝试在启用僵尸的情况下运行,这会在取消引用假定为过时的指针时立即导致崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多