Ленивые переменные в Swift вычисляются более одного раза?
Ленивые переменные в Swift вычисляются более одного раза? У меня сложилось впечатление, что они заменили:
if (instanceVariable) {
return instanceVariable;
}
// set up variable that has not been initialized
Парадигма от Objective-C (ленивый экземпляр).
Это то, что они делают? Обычно вызывается только один раз, когда приложение запрашивает переменную, а затем просто возвращает то, что было рассчитано?
Или он вызывается каждый раз как обычное вычисляемое свойство?
Причина, по которой я спрашиваю, состоит в том, что я в основном хочу вычисляемое свойство в Swift, которое может обращаться к другим переменным экземпляра. Скажем, у меня есть переменная с именем "fullName", и она просто объединяет firstName
а также lastName
, Как бы я сделал это в Swift? Кажется, что ленивые переменные - единственный путь, так как в обычных вычисляемых переменных (не ленивых) я не могу получить доступ к другим переменным экземпляра.
Итак, в основном:
Разве ленивые переменные в Swift называются не раз? Если да, то как мне создать вычисляемую переменную, которая может обращаться к переменным экземпляра? Если нет, если я хочу, чтобы переменная вычислялась только один раз по соображениям производительности, как мне это сделать?
2 ответа
lazy var
s рассчитываются только один раз, при первом использовании. После этого они просто как обычная переменная.
Это легко проверить на детской площадке:
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.
Нет, ленивые свойства инициализируются только один раз. Если вы устанавливаете новое значение или сбрасываете его на ноль (для необязательных свойств), ленивый инициализатор больше не вызывается.
Я думаю, что вам нужно вычисляемое свойство - оно не поддерживается хранимым свойством, поэтому оно не участвует в инициализации, и поэтому вы можете ссылаться на другие свойства экземпляра.
Почему вы говорите, что "нормальные вычисляемые переменные (не ленивые), я не могу получить доступ к другим переменным экземпляра"?
Все остальные ответы верны, я хотел бы добавить, что Apple предупреждает о lazy
переменные и параллелизм:
Если свойство, помеченное модификатором lazy, доступно нескольким потокам одновременно, и свойство еще не инициализировано, нет гарантии, что свойство будет инициализировано только один раз.
Ответы о том, что ленивая переменная может быть вычислена только один раз , не соответствуют действительности. Из документации по адресу https://docs.swift.org/swift-book/LanguageGuide/Properties.html указано следующее:
Если свойство, помеченное модификатором lazy, доступно нескольким потокам одновременно, и свойство еще не инициализировано, нет гарантии, что свойство будет инициализировано только один раз.
Также, пожалуйста, посмотрите этот доклад: https://developer.apple.com/videos/play/wwdc2016/720/. Примерно в 17:00 появляется следующий экран:
Этот доклад дает вам больше понимания многопоточности, я рекомендую вам посмотреть его!