每次访问计算属性时都会对其进行评估吗?

Are computed properties evaluated every time they are accessed?

我有两个关于 Swift 中计算属性的问题。

是否在每次访问计算属性时对其进行评估?或者它们存储在某个地方以供将来访问?

这是什么属性,因为我无法google:

let navigationController: UINavigationController = {
   var navigator = UINavigationController()
   navigator.navigationBar.translucent = false
   return navigator
}()

这个是不是每次访问都要评估?

这不是计算 属性。

let navigationController: UINavigationController = {
   var navigator = UINavigationController()
   navigator.navigationBar.translucent = false
   return navigator
}()

它只是一个 存储的 属性 填充了此代码块 return 值的结果。

var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator

当 class 的实例被实例化时执行该块。只有一次。

所以写这个

struct Person {
    let name: String = {
        let name = "Bob"
        return name
    }() // <- look at these
}

等同于这个

struct Person {
    let name: String
    init() {
        self.name = "Bob"
    }
}

恕我直言,第一种方法更好,因为:

  • 它确实允许您在 相同的 "space"
  • 中声明和填充 属性
  • 清晰
  • 如果您有多个初始值设定项
  • ,则可以防止代码重复

注意 #1:在 属性

中存储闭包

正如下面评论中 dfri 指出的那样,代码块确实以 () 结尾。这意味着代码被 评估 并且结果分配给 属性.

另一方面,如果我们删除块末尾的 (),我们会得到一些不同的东西,事实上,块是 而不是 评估的。 在这种情况下 Swift 尝试将 stored closure 分配给 属性。这将产生编译错误,因为 属性 具有此类型 UINavigationController.

使用正确的语法,我们可以在 属性.

中放置一个闭包
struct Person {
    let sayHello: ()->() = { print("Hello") }
}

现在我们有一个包含闭包的 sayHello 属性。闭包接收 0 个参数并执行 return Void.

let bob = Person()
bob.sayHello // this does NOT execute the code inside closure
bob.sayHello() // this does execute the code in the closure and does print the message

注意#2:让我们谈谈计算属性

所以我们明确了这道题的代码是不是一个Computed Property。 但是,正如 EmilioPelaez 在下面的另一条评论中指出的那样,我们还应该声明 Computed Property 每次 被评估 它被访问。

在下面的示例中,我创建了一个 Computed 属性 age。如您所见,我每次调用它时,块中的代码也会被执行。

计算示例 属性 (age)