Разве ленивые вары в Свифте вычисляются не раз?
Являются ли ленивые вары в Свифте более одного раза? У меня создалось впечатление, что они заменили:
if (instanceVariable) {
return instanceVariable;
}
// set up variable that has not been initialized
Парадигма из Objective-C (ленивая инстанция).
Это то, что они делают? Как правило, только один раз при первом запросе приложения запрашивает переменную, а затем просто возвращает то, что было рассчитано?
Или он получает вызов каждый раз, как нормальное вычисляемое свойство?
Причина, по которой я спрашиваю, заключается в том, что в основном я хочу, чтобы в Swift вычислялось свойство, которое может обращаться к другим переменным экземпляра. Скажем, у меня есть переменная, называемая "fullName", и она просто объединяет firstName
и lastName
. Как мне это сделать в Свифт? Кажется, что ленивые вары - единственный способ пойти, как в нормальных вычислимых варах (не ленивый), я не могу получить доступ к другим переменным экземпляра.
Итак, в основном:
Неужели ленивые вары в Свифте называются более одного раза? Если да, как мне создать вычисленную переменную, которая может обращаться к переменным экземпляра? Если нет, если я хочу, чтобы переменная была вычислена один раз по соображениям производительности, как мне это сделать?
Ответы
Ответ 1
lazy var
вычисляются только один раз, при первом использовании. После этого они как обычная переменная.
Это легко проверить на игровой площадке:
class LazyExample {
var firstName = "John"
var lastName = "Smith"
lazy var lazyFullName : String = {
[unowned self] in
return "\(self.firstName) \(self.lastName)"
}()
}
let lazyInstance = LazyExample()
println(lazyInstance.lazyFullName)
// John Smith
lazyInstance.firstName = "Jane"
println(lazyInstance.lazyFullName)
// John Smith
lazyInstance.lazyFullName = "???"
println(lazyInstance.lazyFullName)
// ???
Если вам нужно будет пересчитать его позже, используйте вычисленное свойство (с переменной поддержки, если оно дорого) - так же, как вы делали в Objective-C.
Ответ 2
Нет, ленивые свойства инициализируются только один раз. Если вы установите новое значение или reset на nil (для дополнительных свойств), ленивый инициализатор снова будет не.
Я думаю, что вам нужно вычислимое свойство - оно не поддерживается сохраненным свойством, поэтому оно не участвует в инициализации, и поэтому вы можете ссылаться на другие свойства экземпляра.
Почему вы говорите, что "нормальные вычислимые вары (не ленивые) я не могу получить доступ к другим переменным экземпляра"?
Ответ 3
Все остальные ответы верны, я просто хотел бы добавить, что Apple предупреждает о lazy
переменных и параллелизме:
Если свойство, помеченное модификатором lazy, доступно нескольким потокам одновременно и свойство еще не инициализировано, нет гарантии, что свойство будет инициализировано только один раз.