Предупреждение верно в том смысле, что использование defer
здесь не меняет порядок выполнения вашей программы, для чего и предназначен оператор. Однако, к сожалению, предложенная замена в противном случае изменяет поведение вашей программы (подана ошибка: SR-10207 ).
Стоит отметить, что использование defer
для запуска наблюдателя свойства - это своего рода хак, который работает только потому, что средство проверки типов считает, что он отличается от контекста deinit
тела. Вы также можете достичь того же результата с помощью выражения замыкания:
deinit {
{ foo = bar }()
}
В идеале, должна быть какая-то форма синтаксиса, которая позволит вам сказать, что Swift «не выполняет здесь прямой доступ к хранилищу», так что такие обходные пути не нужны, но в настоящее время их нет.
Менее хакерский обходной путь - вытащить желаемую логику деинициализатора в отдельный метод, который помещает логику в контекст, где доступ к свойствам осуществляется нормально:
class C {
var bar = ""
var foo: String {
didSet {
// smt
}
}
init(foo: String) { self.foo = foo }
private func doDeinit() {
foo = bar
}
deinit {
doDeinit()
}
}