Почему обозреватель недвижимости не работает с классами?
Использование детской площадки.
У меня есть следующая структура:
struct Foo {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
Я объявил экземпляр из него в качестве наблюдателя свойства со значениями по умолчанию как "Джеймс" для name
и 33 для age
:
var myFoo = Foo(name: "James", age: 33) {
willSet {
print("my foo will be: \(newValue)")
}
didSet {
print("my foo was: \(oldValue)")
}
}
При попытке отредактировать name
из экземпляра:
myFoo.name = "John"
Я мог видеть в журнале:
Мой Фу будет: Фу (имя: "Джон", возраст: 33)
мой Фу был: Фу (имя: "Джеймс", возраст: 33)
что я и ожидал Однако при объявлении Foo
как класс вместо структуры: class Foo
и запустить точно такой же код, ничего не появится в журнале.
В чем причина этого?
1 ответ
Потому что класс является ссылочным типом, а структура является типом значения.
Предположим, что Foo класс.
myFoo
это просто ссылка. поговоркаmyFoo.name = "John"
мутирует объект на месте; новое значение не назначаетсяmyFoo
Поэтому наблюдателю-установщику нечего наблюдать.Предположим, что Foo является структурой. Это тип значения. Это не может быть изменено на месте. Таким образом, говоря
myFoo.name = "John"
фактически заменяет структуру в переменнойmyFoo
с новой структурой; который устанавливает переменную и запускает наблюдатель сеттера.
Вот почему вы можете сказать myFoo.name = "John"
для класса, даже если myFoo
был объявлен с let
(т.е. объект просто мутирует на месте), но вы не можете сделать это со структурой - вы должны были объявить myFoo
с var
так что значение переменной можно заменить.