swift中的set和get方法

在Swift中,`set`和`get`方法用于定义属性的读取和设置行为。Swift中的属性可以是存储型属性(stored properties)或计算型属性(computed properties)。计算型属性没有实际的存储空间,它们的值是动态计算出来的。

一、下面是一些Swift中使用`set`和`get`方法的例子:

### 存储型属性

对于存储型属性,`get`方法默认是存在的,用于读取属性值。`set`方法可以在属性值被设置时执行额外的操作。

```swift
class Person {
    var name: String

    init(name: String) {
        self.name = name
    }

    // 存储型属性,添加自定义的setter和getter
    var age: Int {
        get {
            return _age
        }
        set {
            if newValue > 0 {
                _age = newValue
            } else {
                print("年龄必须大于0")
            }
        }
    }
    private var _age: Int = 0 // 私有的存储变量
}

let person = Person(name: "Alice")
print(person.age) // 使用getter获取age的值
person.age = 30  // 使用setter设置age的值
person.age = -1  // 尝试设置一个无效的年龄,将会打印错误信息
```

### 计算型属性

计算型属性没有存储空间,它们的值是每次访问时计算得出的。

```swift
struct Circle {
    var radius: Double

    // 计算型属性,使用getter来返回面积
    var area: Double {
        get {
            return Double.pi * radius * radius
        }
    }

    // 计算型属性可以没有setter,如果需要setter也可以定义
    var diameter: Double {
        get {
            return 2 * radius
        }
        set {
            radius = newValue / 2
        }
    }
}

let circle = Circle(radius: 10)
print(circle.area) // 使用getter获取面积
circle.diameter = 20 // 使用setter设置直径,这将更新radius
```

二、### 观察者(willSet 和 didSet)

Swift还提供了`willSet`和`didSet`属性观察者,它们允许你在属性值被设置之前或之后执行代码。

```swift
class Account {
    var balance: Double = 0.0 {
        willSet(newBalance) {
            print("即将设置新余额: \(newBalance)")
        }
        didSet {
            if balance < 0 {
                print("余额不足")
            }
        }
    }
}

let account = Account()
account.balance = 100 // 将打印 "即将设置新余额: 100"
account.balance = -50 // 将打印 "即将设置新余额: -50" 然后是 "余额不足"
```

在这些例子中,`get`方法用于获取属性的值,`set`方法用于设置属性的值,并且可以在设置值时执行额外的逻辑。计算型属性的`get`方法定义了如何计算属性的值,而`willSet`和`didSet`观察者提供了在属性值变化前后执行代码的能力。

在Swift中,当你为类或结构体中的属性设置初始值时,并不会触发`willSet`或`didSet`观察者。这是因为初始值是在实例化过程中设置的,此时属性的观察者逻辑尚未开始执行。

在你提供的`Account`类示例中:

```swift
class Account {
    var balance: Double = 0.0 {
        willSet(newBalance) {
            print("即将设置新余额: \(newBalance)")
        }
        didSet {
            if balance < 0 {
                print("余额不足")
            }
        }
    }
}
```

当创建`Account`类的实例时,`balance`属性被初始化为`0.0`,这个值是直接赋值的,不会触发`willSet`或`didSet`观察者。这意味着,当你创建一个`Account`实例时,下面的代码:

```swift
let account = Account()
```

不会打印出任何关于`willSet`或`didSet`的消息。只有当`balance`属性的值在初始化之后被显式修改时,才会触发这些观察者:

```swift
account.balance = 100.0 // 这将触发 willSet 和 didSet
```

在这个例子中,将`balance`设置为`100.0`会触发`willSet`观察者,打印出"即将设置新余额: 100.0",然后设置新值,接着触发`didSet`观察者,但由于新余额是正数,不会打印"余额不足"的消息。如果将`balance`设置为一个负数,比如:

```swift
account.balance = -50.0 // 这将触发 willSet 和 didSet,并打印 "余额不足"
```

此时,`willSet`会先打印出"即将设置新余额: -50.0",然后设置新值,`didSet`会检测到余额不足,并打印出相应的消息。

三、那如果在 didSet观察者 中判断值真正改变时再触发逻辑,该如何实现?

在Swift中,`didSet`观察者默认会在每次属性值被设置时触发,无论新的值是否与旧值不同。如果你只想在属性值真正改变时执行某些逻辑,你可以在`didSet`中添加一个条件判断,来检查新旧值是否不同。

这里是如何实现这一点的示例:

```swift
class Account {
    var balance: Double = 0.0 {
        willSet(newBalance) {
            print("即将设置新余额: \(newBalance)")
        }
        didSet {
            // 只有当余额真正改变时才执行逻辑
            if balance != oldValue {
                print("余额已从 \(oldValue) 改变到 \(balance)")
                if balance < 0 {
                    print("余额不足")
                }
            }
        }
    }
}
```

在这个例子中,`didSet`观察者使用了`oldValue`这个隐含参数,它代表属性在这次赋值之前的值。通过比较`balance`(新值)和`oldValue`(旧值),你可以判断属性值是否真正发生了变化。如果它们不相等,那么你可以执行你的逻辑代码。

使用这种方式,你可以避免在属性值未改变的情况下执行不必要的操作。例如:

```swift
let account = Account() // 初始赋值,不触发 didSet
account.balance = 100.0 // 余额改变,触发 didSet
account.balance = 100.0 // 余额未变,didSet 不会打印余额改变的消息
account.balance = -50.0 // 余额改变,触发 didSet 并检查余额是否不足
```

在这个例子中,只有当`balance`的值从初始值`0.0`变为`100.0`和从`100.0`变为`-50.0`时,`didSet`观察者中的逻辑才会执行。当尝试将`balance`重新设置为`100.0`时,由于新旧值相同,`didSet`不会执行任何操作。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值