Могу ли я использовать didSet в deinit? - PullRequest
0 голосов
/ 15 октября 2018

Я добавил переменную Timer в свой класс и использовал ее наблюдатель didSet для аннулирования старого значения

var timer: Timer? {
    didSet { oldValue?.invalidate() }
}

deinit {
    timer = nil
}

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

1 Ответ

0 голосов
/ 15 октября 2018

Давайте поместим здесь ответ, чтобы мы могли закрыть его.

  • Кажется, что наблюдатели свойств, по-видимому, не работают во время deinit.Это кажется параллельным с тем фактом, что наблюдатели свойств не работают в течение init, но, в отличие от последнего, первое, кажется, нигде четко не задокументировано.

  • Вы может обойти это путем семантического обмана, но не надо!Это похоже на ошибку (и я ее подал).

  • Исходный вариант использования был не очень хорошим для начала.Скрытие аннулирования таймера в замене звучит как потенциальный кошмар обслуживания.Согласен, что аннулирование и замена идут вместе, как ветчина и яйцо, и я всегда пишу метод, который делает недействительным и заменяет, в этом порядке, и направляет все через этот метод.(Это может быть применено в случае необходимости, но я не буду вдаваться в подробности.) Этот метод может быть вызван во время deinit.

ДОПОЛНИТЕЛЬНОЕ ПРИМЕЧАНИЕ : смотреть, при использовании таймера, для проблем управления памятью!Вы можете легко попасть в ситуацию, когда deinit никогда не вызывается , потому что вы сохраняете таймер, но таймер удерживает вас.Затем вам не удастся сделать недействительным таймер, и весь ваш контроллер представления утечет.Вы не жалуетесь на это в своем вопросе, но это связанный вопрос, поэтому я подумал, что лучше пометить его.

...