乐闻世界logo
搜索文章和话题

Swift 中的属性观察器是什么?如何使用 willSet 和 didSet?

2月21日 15:07

Swift 中的属性观察器是什么?如何使用 willSet 和 didSet?

Swift 中的属性观察器用于监控和响应属性值的变化。当属性值被设置时,属性观察器会被触发,允许你在值改变前后执行自定义代码。

属性观察器的类型:

  1. willSet:

    • 在新值存储之前调用
    • 可以访问新值(通过默认参数名 newValue)
    • 可以在设置新值之前执行验证或准备工作
    • 示例:
      swift
      class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to \(newTotalSteps)") } } }
  2. didSet:

    • 在新值存储之后调用
    • 可以访问旧值(通过默认参数名 oldValue)
    • 可以在值改变后执行更新或通知操作
    • 示例:
      swift
      class StepCounter { var totalSteps: Int = 0 { didSet { print("Added \(totalSteps - oldValue) steps") } } }

完整示例:

swift
class TemperatureMonitor { var temperature: Double { willSet { print("Temperature will change from \(temperature) to \(newValue)") if newValue > 100 { print("Warning: High temperature!") } } didSet { print("Temperature changed from \(oldValue) to \(temperature)") if temperature != oldValue { notifyTemperatureChange() } } } func notifyTemperatureChange() { print("Notifying temperature change...") } } let monitor = TemperatureMonitor() monitor.temperature = 25 monitor.temperature = 105

属性观察器的使用场景:

  1. 数据验证:

    swift
    class Person { var age: Int { didSet { if age < 0 { age = 0 } if age > 150 { age = 150 } } } }
  2. UI 更新:

    swift
    class ViewModel { var isLoading: Bool = false { didSet { updateLoadingIndicator() } } func updateLoadingIndicator() { // 更新 UI 指示器 } }
  3. 缓存失效:

    swift
    class DataCache { var data: [String: Any] = [:] { didSet { invalidateCache() } } func invalidateCache() { // 清除缓存 } }
  4. 日志记录:

    swift
    class Logger { var logLevel: LogLevel = .info { didSet { print("Log level changed from \(oldValue) to \(logLevel)") } } }

注意事项:

  1. 属性观察器不能用于延迟属性(lazy)
  2. 属性观察器不能用于常量属性(let)
  3. 在初始化器中设置属性值不会触发属性观察器
  4. 在 willSet 中修改属性值不会再次触发 willSet
  5. 在 didSet 中修改属性值会再次触发属性观察器
  6. 如果属性有默认值,初始化时不会触发属性观察器

最佳实践:

  1. 使用 willSet 进行值验证和准备
  2. 使用 didSet 执行副作用和更新
  3. 避免在属性观察器中执行耗时操作
  4. 注意避免无限循环(在 didSet 中修改属性)
  5. 使用有意义的参数名提高代码可读性
标签:Swift