You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何属性观察器在类中无法生效?Playground场景技术咨询

Why Your Property Observers Aren't Triggering (And How to Fix It)

Hey there, let's break down what's happening with your code and clear up that confusion about classes too.

First: Why Your Struct's Property Observer Isn't Firing

The key issue here is where you've attached the property observers. You added willSet and didSet to the myFoo variable itself, not to the individual properties (name/age) inside the Foo struct.

Let's look at your code again:

// Observers are attached to the myFoo variable, not Foo's properties
var myFoo = Foo(name: "James", age: 33) { 
    willSet { 
        print("my foo will be: \(newValue)") 
    } 
    didSet { 
        print("my foo was: \(oldValue)") 
    } 
}

This means these observers only trigger when you completely replace the myFoo variable (i.e., assign a brand new Foo instance to it), like this:

myFoo = Foo(name: "Alice", age: 34) // This will trigger willSet and didSet

Modifying a property inside the existing instance (myFoo.name = "Alice") won't trigger these observers because the myFoo variable itself isn't being reassigned—even though structs are value types, changing an internal property doesn't count as replacing the entire variable in the eyes of these top-level observers.

The Fix: Attach Observers to the Struct's Properties

If you want to react when name or age changes, move the observers directly into the Foo struct's properties:

struct Foo { 
    var name: String {
        willSet {
            print("Name is changing to: \(newValue)")
        }
        didSet {
            print("Name was: \(oldValue)")
        }
    }
    var age: Int {
        willSet {
            print("Age is changing to: \(newValue)")
        }
        didSet {
            print("Age was: \(oldValue)")
        }
    }
    init(name: String, age: Int) { 
        self.name = name 
        self.age = age 
    } 
}

var myFoo = Foo(name: "James", age: 33)
myFoo.name = "Alice" // Now this will trigger the name property's observers!

Second: Property Observers Do Work in Classes (You Just Need to Use Them Right)

Your confusion about classes comes from the same variable vs. property distinction, plus how reference types work.

Classes are reference types, so when you have a variable holding a class instance, that variable stores a reference to the instance (not the instance itself). If you attach observers to the variable, they only trigger when you change which instance the variable points to (i.e., reassign the variable). Modifying properties on the existing instance won't trigger the variable's observers because the reference itself hasn't changed.

But if you attach observers directly to the class's properties, they work exactly like they do in structs:

class Bar {
    var name: String {
        willSet {
            print("Class name will be: \(newValue)")
        }
        didSet {
            print("Class name was: \(oldValue)")
        }
    }
    init(name: String) {
        self.name = name
    }
}

var myBar = Bar(name: "James")
myBar.name = "Bob" // Triggers the name property's observers perfectly

Quick Recap

  • Attach observers to individual properties (inside structs/classes) if you want to react when that property changes.
  • Attach observers to a top-level variable only if you care when the entire instance (for structs) or the reference (for classes) is replaced.

内容的提问来源于stack exchange,提问作者Ahmad F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:11:14