Swift 中的 dealloc

我想在视图控制器的生命周期结束时执行一些清理,即删除一个 NSNotificationCenter通知。实现 dealloc会导致 Swift 编译器错误:

Cannot override 'dealloc' which has been marked unavailable

在 Swift 中,在对象生命结束时执行某些清理的首选方法是什么?

75684 次浏览
deinit {
// perform the deinitialization
}

来自 快速文档:

在调用类实例之前立即调用反初始化器 用 deinit 关键字编写去初始化器,类似于 如何使用 init 关键字编写初始化器 只对类类型有效。

时,通常不需要执行手动清理 实例被释放。但是,当您使用自己的 资源时,可能需要执行一些额外的清理 例如,如果您创建一个自定义类来打开一个文件和 写入一些数据之前,可能需要关闭该文件 类实例被释放。

Https://developer.apple.com/library/content/documentation/swift/conceptual/swift_programming_language/deinitialization.html

当不再需要实例时,Swift 会自动释放实例,以释放资源。Swift 通过自动引用计数(ARC)处理实例的内存管理,如自动引用计数中所述。在释放实例时,通常不需要执行手动清理。但是,当您使用自己的资源时,您可能需要自己执行一些额外的清理工作。例如,如果创建自定义类以打开文件并向其写入一些数据,则可能需要在释放类实例之前关闭该文件。

类定义每个类最多只能有一个反初始化器。取消初始值设定项不带任何参数,并且写入时不带括号:

deinit {
// perform the deinitialization
}
deinit {
// perform the deinitialization
}

正确答案是 Swift 的“ dealloc”。

然而,在 iOS9中很好地指出,NSNotificationCenter 不再需要清理!

Https://developer.apple.com/library/content/releasenotes/foundation/rn-foundationoldernotes/index.html#x10_11notes

NSNotificationCenter

在 OS X 10.11和 iOS 9.0中,NSNotificationCenter 和 NSDibutedNotificationCenter 将不再向可能被释放的注册观察员发送通知。如果观察者能够被存储为弱零引用,那么底层存储将把观察者存储为弱零引用,或者,如果对象不能被弱存储(例如,它有一个自定义的保留/释放机制,可以防止运行时能够弱存储对象) ,那么它将把对象存储为非弱零引用。这意味着观察者不需要在其释放方法中注销注册。路由到该观察者的下一个通知将检测到零引用并自动取消注册该观察者。如果对象可以被弱引用,则在释放期间将不再向观察者发送通知; 在非弱零引用观察者的情况下,在释放期间接收通知的先前行为仍然存在。通过-[ NSNotificationCenter addObserverForName: object: queue: usingBlock ]方法的基于块的观察者在不再使用时仍然需要取消注册,因为系统仍然保留对这些观察者的强引用。仍然支持过早删除观察器(弱引用或归零引用)。CFNotificationCenterAddObserver 不符合此行为,因为观察者可能不是对象。

但是请注意下面关于强引用的要点,所以无论如何您可能都要担心清理问题... ... ?

Deinit调用其他类中的方法时要小心,它可能会以崩溃告终

在释放之前需要删除观察者,否则会发生崩溃

deinit {
// perform the deinitialization
print("deinit")


removeObserver(self, forKeyPath: kSelectedViewControllerKey, context: nil)
removeObserver(self, forKeyPath: kSelectedIndexKey, context: nil)


}

如果你真的想在 view 超出作用域时删除一些东西,并在作用域内启动,我建议我们使用控制器的 did 显示和 did 消失方法。当视图出现/消失时,甚至 NSNotificationCenter 也可以删除和添加回来。