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

What are property observers in Swift? How to use willSet and didSet?

2月21日 15:07

What are property observers in Swift? How to use willSet and didSet?

Property observers in Swift are used to monitor and respond to changes in property values. When a property value is set, property observers are triggered, allowing you to execute custom code before and after the value changes.

Types of Property Observers:

  1. willSet:

    • Called before the new value is stored
    • Can access the new value (via default parameter name newValue)
    • Can perform validation or preparation before setting the new value
    • Example:
      swift
      class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to \(newTotalSteps)") } } }
  2. didSet:

    • Called after the new value is stored
    • Can access the old value (via default parameter name oldValue)
    • Can perform updates or notifications after the value changes
    • Example:
      swift
      class StepCounter { var totalSteps: Int = 0 { didSet { print("Added \(totalSteps - oldValue) steps") } } }

Complete Example:

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

Use Cases for Property Observers:

  1. Data Validation:

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

    swift
    class ViewModel { var isLoading: Bool = false { didSet { updateLoadingIndicator() } } func updateLoadingIndicator() { // Update UI indicator } }
  3. Cache Invalidation:

    swift
    class DataCache { var data: [String: Any] = [:] { didSet { invalidateCache() } } func invalidateCache() { // Clear cache } }
  4. Logging:

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

Important Notes:

  1. Property observers cannot be used with lazy properties
  2. Property observers cannot be used with constant properties (let)
  3. Setting property values in initializers does not trigger property observers
  4. Modifying property values in willSet does not trigger willSet again
  5. Modifying property values in didSet triggers property observers again
  6. If a property has a default value, property observers are not triggered during initialization

Best Practices:

  1. Use willSet for value validation and preparation
  2. Use didSet for side effects and updates
  3. Avoid performing time-consuming operations in property observers
  4. Be careful to avoid infinite loops (modifying property in didSet)
  5. Use meaningful parameter names to improve code readability
标签:Swift