【问题标题】:Why does NSObject get deallocated while it presents its UIViewController?为什么 NSObject 在呈现其 UIViewController 时会被释放?
【发布时间】:2016-04-18 14:40:21
【问题描述】:

NSObject 提供了一个视图控制器:

class myObject: NSObject {

    var myVC = UIViewController()

    func present() {
        let rootVC = UIApplication.sharedApplication().keyWindow!.rootViewController
        rootVC.presentViewController(myVC, animated: animated, completion: nil)
    }
}

myVC 出现并且在屏幕上仍然可见时,为什么myObject 会被释放(调用deinit)?它不应该保持分配状态,因为myVC 是它的属性吗?

更新:我面临的有效问题是myVC 显示了一个带有控件的视图,其代表是myObject。因为myObject 已解除分配,所以控件无法再调用委托,因为我将委托引用为weak。但是,当我对委托 myObject 有强烈引用时,仍会分配并调用委托。但是对代理使用强引用有点可疑。

【问题讨论】:

  • 委托通常是弱引用,因此行为是预期的。呈现的控制器不拥有委托!
  • 架构问题。您的对象是您的控制器的所有者,但没有人拥有该对象,因此它被释放。
  • 可能是因为没有人持有对 MyObject 的引用...这是呈现/关闭 UIViewController 的错误方式,为什么要将它包装到 MyObject 中?您应该在没有任何中介的情况下从另一个 ViewController 实例中显示一个 viewController,并且您不会遇到委派问题
  • 谢谢大家,这当然是有道理的。我想我会让 myObject 成为一个单例来解决这个问题。在我的例子中,myObject 配置了视图控制器,但配置非常复杂,我宁愿在呈现视图控制器的代码中没有它。
  • 如果你想这样做,但建议至少将 myObject 重命名为 DisplayController 之类的名称或符合逻辑的名称

标签: ios swift memory-management uiviewcontroller nsobject


【解决方案1】:

ARC 内存管理基于所有权。一旦一个对象不属于任何其他对象,它就会被释放。总有一个根对象拥有所有其他对象 - UIApplication。应用程序中所有对象的所有权可以用树来描述:

UIApplication
  - UIApplicationDelegate
       - rootViewController
            - child controllers
               - child controllers ...
       - window
            - subviews
               - subviews ...
       - ... other objects

当然,您可以创建其他根对象(其他所有权树),例如通过使用单例。

如果您的实例不属于此层次结构树中的对象,则它会被释放。因此,您应该以控制器仅由其他控制器拥有,而不是由自定义对象拥有的方式来构建您的所有权层次结构。

如果您需要对所有者的引用,通常是使用weak 引用的时候,以避免循环所有权。

还请注意,UIViewController 在堆上占用了一些重要的内存,因此在不需要它们时保留对它们的引用并不常见。在呈现之前创建新实例更为常见(尽管存在例外)。

【讨论】:

  • 那么,当用户注销时,可以在整个应用程序流程中随时呈现的“登录视图控制器”的最佳实践是什么?登录视图包含触发委托中的功能的按钮,目前是一个 NSObject。如果我从所有权树中删除了 NSObject,我必须在每个调用视图控制器中移动配置。我只能考虑用另一个视图控制器替换 myObject ,该控制器除了配置和呈现登录视图控制器之外什么都不做,但这似乎也没有效率。
  • @Manuel 我认为您应该将其放入应用程序委托(例如使用类别)或根视图控制器中。根视图控制器通常是处理此类事情的地方。您实际上是在代码中访问该控制器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
相关资源
最近更新 更多