dealloc в Swift


Я хотел бы выполнить некоторую очистку в конце жизни контроллера вида, а именно удалить NSNotificationCenter уведомления. Реализация dealloc приводит к ошибке компилятора Swift:

Cannot override 'dealloc' which has been marked unavailable

каков предпочтительный способ выполнить некоторую очистку в конце жизни объекта в Swift?

5 123

5 ответов:

deinit {
    // perform the deinitialization
}

С Swift Documentation:

деинициализатор вызывается непосредственно перед экземпляром класса освободившему. Вы пишете deinitializers с ключевым словом deinit, похожие как инициализаторы пишутся с сайта инит. Деинитализаторы доступны только для типов классов.

обычно вам не нужно выполнять ручную очистку, когда ваш экземпляры освобождаются. Однако, когда вы работаете с вашим собственным ресурсов, возможно, потребуется выполнить некоторые дополнительные очистки себе. Например, если вы создадите пользовательский класс для открытия файла и напишите некоторые данные к нему, вы могли закрыть архив перед экземпляр класса освобождается.

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 больше не будет отправлять уведомления зарегистрированным наблюдателям, которые могут быть освобождены. Если наблюдатель может быть сохранен как слабая ссылка на обнуление, базовое хранилище будет хранить наблюдателя как слабую ссылку на обнуление, альтернативно, если объект не может быть сохранен слабо (т. е. у него есть пользовательский механизм удержания/освобождения, который помешает среде выполнения хранить объект слабо), он будет хранить объект как неслабую ссылку на обнуление. Это средство что наблюдатели не обязаны отменять регистрацию в своем методе освобождения. Следующее уведомление, которое будет направлено этому наблюдателю, обнаружит обнуленную ссылку и автоматически отменит регистрацию наблюдателя. Если объект может быть слабо привязан, уведомления больше не будут отправляться наблюдателю во время освобождения; предыдущее поведение получения уведомлений во время освобождения все еще присутствует в случае неслабого обнуления опорных наблюдателей. Блок на основе наблюдателей через - [NSNotificationCenter addObserverForName:object:queue:usingBlock] метод по-прежнему должен быть незарегистрированным, когда он больше не используется, поскольку система по-прежнему содержит сильную ссылку на этих наблюдателей. По-прежнему поддерживается преждевременное удаление наблюдателей (либо со слабой ссылкой, либо с нулевой ссылкой). CFNotificationCenterAddObserver не соответствует этому поведению, так как наблюдатель не может быть объектом.

но обратите внимание на пункты ниже о сильных ссылок, поэтому вы можете беспокоиться о чистке в любом случае...?

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

Swift автоматически освобождает ваши экземпляры, когда они больше не нужны, чтобы освободить ресурсы. Swift обрабатывает управление памятью экземпляров с помощью автоматического подсчета ссылок (ARC), как описано в разделе автоматический подсчет ссылок. Обычно вам не нужно выполнять ручную очистку, когда ваши экземпляры освобождены. Однако при работе с собственными ресурсами может потребоваться выполнить дополнительную очистку самостоятельно. Например, если вы создаете пользовательский класс для открытия файла и записи в него некоторых данных, вам может потребоваться закрыть файл, прежде чем экземпляр класса будет освобожден.

определения классов могут иметь не более одного деинициализатора на класс. Деинициализатор не принимает никаких параметров и записывается без скобок:

 deinit
   {

     // perform the deinitialization

    }

будьте осторожны при вызове метода в другой класс deinit это, вероятно, в конечном итоге в аварии

удаление наблюдателя требуется перед освобождением в противном случае произойдет сбой. Это можно сделать с помощью

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

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

}