计算属性与带闭包属性集之间的差异

我是斯威夫特的新手。计算属性和设置为闭包的属性之间的区别是什么?我知道计算属性每次都会重新计算。关闭的时候有什么不同吗?也就是说。

关闭:

var pushBehavior: UIPushBehavior = {
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}()

计算结果:

var pushBehavior: UIPushBehavior {
get{
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}
}
21529 次浏览

The main difference is that you cannot assign something to the computed property since it has no setter. In this case the closure only gets called once and the return value gets stored in the variable so if the outcome doesn't change over time it is more efficient to use the stored variable rather than the computed one.

In general: computed properties should only be used if the value can be retrieved quickly.

Sidenote: If you don't change/reassign the stored variable you should consider making it a constant (let)

In short, the first is a stored property that is initialized via a closure, with that closure being called only one time, when it is initialized. The second is a computed property whose get block is called every time you reference that property.


The stored property’s initialization closure is called once and only once, but you can later change the value of the stored property (unless you replace var with let). This is useful when you want to encapsulate the code to initialize a stored property in a single, concise block of code.

The computed property’s block, however, is called each time you reference the variable. It’s useful when you want the code to be called every time you reference the computed property. Generally you do this when the computed property needs to be recalculated every time you reference the stored property (e.g. recalculated from other, possibly private, stored properties).

In this case, you undoubtedly want the stored property (the first example), not the computed property (the second example). You presumably don't want a new push behavior object each time you reference the variable.


By the way, in your first example, you internally reference to it being instantiated lazily. If you want that behavior, you must use the lazy keyword:

lazy var pushBehavior: UIPushBehavior = {
let behavior = UIPushBehavior()
behavior.setAngle(50, magnitude: 50)
return behavior
}()

If, however, the property is static, it is automatically instantiated lazily.

Closure :

  //closure
var pushBehavior: UIPushBehavior = {
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}()

At first time when pushBehavior variable called then block execute and value is saved in pushBehavior variable. after that whenever you call pushBehavior then those value are returned.

means only first-time block code executed and saved in this variable. Also, you can store variable value whenever you want but after that, those value returned but if you declare as "let" then you can't change this value.

Computed property :

var pushBehavior: UIPushBehavior {
get{
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}
}

In computed property whenever you called pushBehavior variable then this block execute and value return. so every time block is executed. and you can not declare variable as "let" keyword for pushBehavior variable.

So you can use this code as per your requirement.

This isn't an answer, but it's just worth mentioning that for:

  • A stored property's value must be known after initializing completes. That happens either by defaulting or through initialization.
  • A computed property's value isn't computed until it's accessed
  • A lazy loaded property's value isn't defined until it's accessed

Hence for both computed and lazy variables you can access self or stored properties with no worries.