斯威夫特的dealloc

时间:2014-08-26 04:12:50

标签: swift dealloc

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

Cannot override 'dealloc' which has been marked unavailable

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

6 个答案:

答案 0 :(得分:314)

deinit {
    // perform the deinitialization
}

来自Swift Documentation

  

在类实例之前立即调用deinitializer   释放。您使用deinit关键字编写deinitializers,类似   如何使用init关键字编写初始化器。 Deinitializers   仅适用于班级类型。

     

通常,您不需要执行手动清理   实例被解除分配。但是,当您使用自己的时   资源,您可能需要执行一些额外的清理   你自己。例如,如果您创建一个自定义类来打开文件和   向它写一些数据,你可能需要先关闭文件   类实例被解除分配。

答案 1 :(得分:42)

deinit {
    // perform the deinitialization
}

是Swift“dealloc”的正确答案。

但是,最好在iOS 9中指出不再需要清理NSNotificationCenter!

https://developer.apple.com/library/content/releasenotes/Foundation/RN-FoundationOlderNotes/index.html#X10_11Notes

  

<强> NSNotificationCenter

     

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

但请注意以下关于强引用的要点,所以无论如何你可能不得不担心清理......?

答案 2 :(得分:20)

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

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

每个类的类定义最多只能有一个deinitializer。 deinitializer不带任何参数,并且没有括号:

 deinit
   {

     // perform the deinitialization

    }

答案 3 :(得分:1)

在解除分配之前,必须先移除观察器,否则将导致崩溃。可以使用

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

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

}

答案 4 :(得分:0)

如果您真的想在视图超出范围时删除某些东西,而在范围内开始时,我建议让我们在控制器的didAppear和didDisappear方法中进行操作。当视图出现/消失时,甚至NSNotificationCenter也可以删除并重新添加。

答案 5 :(得分:-1)

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