Swift中的懒惰变量是不是一次计算过的?

问题描述 投票:24回答:4

Swift中的懒惰变量是不是一次计算过的?我的印象是他们取代了:

if (instanceVariable) {
    return instanceVariable;
}

// set up variable that has not been initialized

来自Objective-C的范例(懒惰的实例化)。

那是他们做的吗?基本上只在第一次应用程序要求变量时调用,然后才返回计算的内容?

或者它每次都像普通的计算属性一样被调用?

我问的原因是因为我基本上想要一个可以访问其他实例变量的Swift中的计算属性。假设我有一个名为“fullName”的变量,它只是连接firstNamelastName。我怎么会在Swift中这样做?似乎懒惰变量是唯一的方法,因为在正常的计算变量(非惰性)中我无法访问其他实例变量。

所以基本上:

Swift中的懒惰变量不止一次被调用吗?如果是这样,我如何创建一个可以访问实例变量的计算变量?如果没有,如果出于性能原因我只想要计算一次变量,我该怎么做?

swift lazy-initialization computed-properties
4个回答
23
投票

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中所做的那样。


6
投票

不,懒惰属性只初始化一次。如果设置新值或重置为nil(对于可选属性),则不会再次调用惰性初始值设定项。

我认为你需要的是一个计算属性 - 它没有存储属性的支持,所以它不参与初始化,因此你可以引用其他实例属性。

为什么这么说“正常的计算变量(非惰性)我无法访问其他实例变量”?


1
投票

所有其他答案都是正确的,我只想补充一点,Apple警告lazy变量和并发性:

如果同时由多个线程访问标记为延迟修饰符的属性且该属性尚未初始化,则无法保证该属性仅初始化一次。


1
投票

回答声明懒惰var只能计算一次是不正确的。从https://docs.swift.org/swift-book/LanguageGuide/Properties.html的文档中,陈述如下:

如果同时由多个线程访问标记为延迟修饰符的属性且该属性尚未初始化,则无法保证该属性仅初始化一次。

另外,请看这个演讲:https://developer.apple.com/videos/play/wwdc2016/720/。在17:00左右,出现以下屏幕:

enter image description here

那个讲座让你对多线程有了更多的了解,我建议你观看它!

© www.soinside.com 2019 - 2024. All rights reserved.