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