Ленивые переменные в Swift вычисляются более одного раза?

Ленивые переменные в Swift вычисляются более одного раза? У меня сложилось впечатление, что они заменили:

if (instanceVariable) {
    return instanceVariable;
}

// set up variable that has not been initialized

Парадигма от Objective-C (ленивый экземпляр).

Это то, что они делают? Обычно вызывается только один раз, когда приложение запрашивает переменную, а затем просто возвращает то, что было рассчитано?

Или он вызывается каждый раз как обычное вычисляемое свойство?

Причина, по которой я спрашиваю, состоит в том, что я в основном хочу вычисляемое свойство в Swift, которое может обращаться к другим переменным экземпляра. Скажем, у меня есть переменная с именем "fullName", и она просто объединяет firstName а также lastName, Как бы я сделал это в Swift? Кажется, что ленивые переменные - единственный путь, так как в обычных вычисляемых переменных (не ленивых) я не могу получить доступ к другим переменным экземпляра.

Итак, в основном:

Разве ленивые переменные в Swift называются не раз? Если да, то как мне создать вычисляемую переменную, которая может обращаться к переменным экземпляра? Если нет, если я хочу, чтобы переменная вычислялась только один раз по соображениям производительности, как мне это сделать?

2 ответа

lazy vars рассчитываются только один раз, при первом использовании. После этого они просто как обычная переменная.

Это легко проверить на детской площадке:

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 появляется следующий экран:

Этот доклад дает вам больше понимания многопоточности, я рекомендую вам посмотреть его!

Другие вопросы по тегам