为什么 NSObject 在呈现其 UIViewController 时会被释放?
Why does NSObject get deallocated while it presents its UIViewController?
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
保持分配状态并且委托被调用。但是为委托使用强引用有点可疑。
ARC 内存管理基于所有权。一旦一个对象不属于任何其他对象,它就会被释放。总有一个根对象拥有所有其他对象 - UIApplication
。应用中所有对象的所有权可以用树来描述:
UIApplication
- UIApplicationDelegate
- rootViewController
- child controllers
- child controllers ...
- window
- subviews
- subviews ...
- ... other objects
当然,您可以创建其他根对象(其他所有权树),例如通过使用单例。
如果您的实例不属于此层次结构树中的对象,它将被释放。因此,您应该以控制器仅由其他控制器而非自定义对象拥有的方式构建您的所有权层次结构。
如果您需要对所有者的引用,通常是时候使用 weak
引用,以避免循环所有权。
另请注意,UIViewController
会在堆上占用大量内存,因此在不需要时保留对它们的引用并不是很常见。在呈现之前创建新实例更为常见(尽管存在例外)。
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
保持分配状态并且委托被调用。但是为委托使用强引用有点可疑。
ARC 内存管理基于所有权。一旦一个对象不属于任何其他对象,它就会被释放。总有一个根对象拥有所有其他对象 - UIApplication
。应用中所有对象的所有权可以用树来描述:
UIApplication
- UIApplicationDelegate
- rootViewController
- child controllers
- child controllers ...
- window
- subviews
- subviews ...
- ... other objects
当然,您可以创建其他根对象(其他所有权树),例如通过使用单例。
如果您的实例不属于此层次结构树中的对象,它将被释放。因此,您应该以控制器仅由其他控制器而非自定义对象拥有的方式构建您的所有权层次结构。
如果您需要对所有者的引用,通常是时候使用 weak
引用,以避免循环所有权。
另请注意,UIViewController
会在堆上占用大量内存,因此在不需要时保留对它们的引用并不是很常见。在呈现之前创建新实例更为常见(尽管存在例外)。