Нужно ли отменять deinit для удаления наблюдателей в Swift? - PullRequest
0 голосов
/ 24 февраля 2020

Товарищи по команде написали код наподобие

deinit {
    NotificationCenter.default.removeObserver(self)
}

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

Должен ли я также вызвать super.deinit() внутри deinit?

Ответы [ 2 ]

6 голосов
/ 24 февраля 2020

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

Если наблюдатель может быть сохранен как ссылка со слабым обнулением, базовое хранилище будет хранить наблюдатель как нулевая слабая ссылка, в противном случае, если объект не может быть сохранен слабо (т. е. у него есть собственный механизм сохранения / освобождения, который препятствует тому, чтобы среда выполнения могла сохранять объект слабо), он сохранит объект как неслабый Обнуление ссылки. Это означает, что наблюдатели не обязаны отменять регистрацию в своем методе освобождения.

Блочные наблюдатели с помощью метода - [NSNotificationCenter addObserverForName: object: queue: usingBlock] по-прежнему должны быть незарегистрированными, когда они больше не находятся в использовать, так как система все еще имеет сильную ссылку на этих наблюдателей.

Apple Docs

и для super.deinit () яблоко говорит

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

swift docs

1 голос
/ 24 февраля 2020

Да, допустимо переопределить

deinit()

Как указано в комментариях. Супер не нужно называть. Я подтвердил это в документах Apple.

Явная очистка - это хорошая идея. Особенно когда дело доходит до потоков, уведомлений и таймеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...