在属性内使用它时,willSet
- didSet
和 get
- set
有什么区别?
从我的角度来看,它们都可以为属性设置值。我应该何时以及为什么使用willSet
- didSet
,以及何时get
- set
?
我知道对于willSet
和didSet
,结构如下所示:
var variable1 : Int = 0 {
didSet {
println (variable1)
}
willSet(newValue) {
..
}
}
var variable2: Int {
get {
return variable2
}
set (newValue){
}
}
何时以及为什么应该使用 willSet/didSet
-
willSet
是在存储值之前调用的。 -
didSet
在存储新值后立即调用。
考虑您的输出示例:
var variable1 : Int = 0 {
didSet{
print("didSet called")
}
willSet(newValue){
print("willSet called")
}
}
print("we are going to add 3")
variable1 = 3
print("we added 3")
输出:
we are going to add 3
willSet called
didSet called
we added 3
它的工作原理类似于前/后条件
另一方面,如果要添加只读属性,则可以使用 get
:
var value : Int {
get {
return 34
}
}
print(value)
value = 2 // error: cannot assign to a get-only property 'value'
@Maxim的答案是针对您问题的第一部分。
至于何时使用get
和set
:当您需要计算属性时。这:
var x: Int
创建一个存储属性,该属性由变量自动备份(但不能直接访问(。将值设置为该属性将转换为设置属性中的值,同样用于获取。
相反:
var y = {
get { return x + 5 }
set { x = newValue - 5}
}
将创建一个计算属性,该属性不由变量备份 - 相反,您必须提供 getter 和/或 setter 的实现,通常从另一个属性读取和写入值,更一般地作为计算的结果(因此计算属性名称(
推荐阅读: 属性
注意:您的代码:
var variable2: Int {
get{
return variable2
}
set (newValue){
}
}
是错误的,因为在get
中,您正在尝试返回自身,这意味着递归调用get
。实际上,编译器会通过类似 Attempting to access 'variable2' within its own getter
.
var variable1 : Int = 0 { //It's a store property
didSet {
print (variable1)
}
willSet(newValue) {
..
}
}
var variable2: Int { //It's a Computed Proprties
get {
return variable2
}
set (newValue){
}
}
有关应用商店属性和计算属性
的详细信息因此,当您尝试在该分配时间将值分配给变量时,会出现"didSet"和"willSet"的概念。正如@Maxim所说
- 在存储值之前调用 willSet。
- 在存储新值后立即调用 didSet。
"willSet"和"didSet"的例子:
class Number {
var variable1 : Int = 0 {
didSet{
print("didSet called")
}
willSet(newValue){
print("willSet called")
}
}
}
print("we are going to add 3")
Number().variable1 = 3
print("we added 3")
//o/p:
我们将添加 3 个
名为
didSet 的 willSet 叫
我们加了3
通常,当两个属性依赖时,使用"get"和"set"。(它也用于协议,这是不同的概念。
get"和"set"的示例:
class EquilateralTriangle{
var sideLength: Double = 0.0
init(sideLength: Double){
self.sideLength = sideLength
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
}
var triangle = EquilateralTriangle(sideLength: 3.0)
print(triangle.perimeter) //o/p: 9.0
triangle.perimeter = 12.0
print(triangle.sideLength) //o/p: 4.0
设置:
get
set
是计算属性,它们实际上并不存储 值。相反,它们提供了一个吸气器和一个可选的二传手 间接检索和设置其他属性和值
此外,还可以定义只读计算属性。只读计算属性始终返回一个值,并且可以通过点语法访问,但不能设置为其他值
示例仅获取属性-
var number: Double {
return .pi*2
}
将设置didSet:
属性观察
willSet
didSet
是财产观察员者观察并响应属性的更改 价值。每次属性的值为 设置,即使新值与属性的当前值相同 价值。
- 在存储值之前调用 willSet。
- 在存储新值后立即调用 didSet。
例-
var score: Int = 0 {
willSet(newScore) {
print("willSet score to (newScore)")
}
didSet {
print("didSet score to (oldValue) new score is: (score)")
}
}
score = 10
//Output
//willSet score to 10
//didSet score to 0 new score is: 10
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html
设置
如果要实现 gettable 和 setable 属性,可以使用常规get-and-set
语法。但是,如果实现read-only
属性,则可以只使用get
语法。有了setter
,您将获得newValue
属性。
class GetterSetter {
var theValue: Bool = false
var property: Bool {
get { return theValue }
set {
print("Value changed from (theValue) to (newValue)")
theValue = newValue
}
}
}
let getterSetter = GetterSetter()
getterSetter.property = true
getterSetter.property
// PRINTS:
// Value changed from 'false' to 'true'
迪德集
didSet
属性观察器用于我们需要在刚刚设置属性时执行代码的情况。实现didSet
为您提供oldValue
来表示以前的值。
class DidSetter {
var property: Float16 = -1.0 {
didSet {
print("Value changed from (oldValue) to (property)")
}
}
}
let didSetter = DidSetter()
didSetter.property = 5.0
didSetter.property
// PRINTS:
// Value changed from -1.0 to 5.0
将设置
willSet
属性观察器用于我们需要在设置属性之前执行代码的情况。实现willSet
,您将获得newValue
来表示它将要成为的新属性值。
class WillSetter {
var property: String = "NO" {
willSet {
print("Value changed from (property) to (newValue)")
}
}
}
let willSetter = WillSetter()
willSetter.property = "YES"
willSetter.property
// PRINTS:
// Value changed from NO to YES