> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Swift Property Observer

Property observers are specialized code blocks that observe and respond to mutations of a property's or variable's value. They are invoked synchronously every time a value is set, regardless of whether the incoming value is identical to the existing value.

Swift provides two distinct observer blocks:

* **`willSet`**: Executed immediately *before* the new value is stored in memory. It provides an implicit constant parameter named `newValue` representing the incoming value.
* **`didSet`**: Executed immediately *after* the new value is stored in memory. It provides an implicit constant parameter named `oldValue` representing the pre-mutation value. If a new value is assigned to the property within its own `didSet` block, this new value replaces the one that was just set. This internal assignment does *not* trigger the observer again, preventing infinite recursion.

## Syntax

You can define either or both observers on a declaration. You may also explicitly name the injected parameters to override the default `newValue` and `oldValue` identifiers.

```swift theme={"dark"}
var observedProperty: Int = 0 {
    willSet {
        // Executes before assignment. 
        // The implicit parameter 'newValue' is available here.
    }
    didSet(customOldValueName) {
        // Executes after assignment. 
        // The parameter is explicitly named 'customOldValueName' instead of 'oldValue'.
        
        // Assigning a value here replaces the recently set value 
        // without re-triggering willSet or didSet.
        if observedProperty > 100 {
            observedProperty = 100 
        }
    }
}
```

## Applicability and Constraints

Property observers can be attached to specific declarations under strict conditions:

1. **Defined Stored Properties**: Can be applied to any stored property defined within a class or struct, with the exception of `lazy` stored properties.
2. **Global and Local Variables**: Can be applied to global variables (defined at the file scope) and local variables (defined within functions or closures).
3. **Inherited Stored Properties**: Can be applied by overriding an inherited stored property in a subclass.
4. **Inherited Computed Properties**: Can be applied by overriding an inherited computed property. (For non-inherited computed properties, observation logic must be placed directly inside the property's standard `set` block).

## Initialization Behavior

Property observers are **not** triggered during the initialization phase of an instance or variable. Specifically, `willSet` and `didSet` are bypassed when:

* A property or variable is assigned its initial default value at the declaration site.
* A property is assigned a value within the type's own initializer (`init`).

*Note:* If a subclass initializer sets the value of an inherited property after calling the superclass initializer (`super.init()`), the superclass's property observers *will* be triggered, as the initialization phase for that specific property is considered complete.

## In-Out Parameter Mechanics

When a property or variable equipped with observers is passed to a function as an `inout` parameter, both `willSet` and `didSet` are guaranteed to execute. This is a byproduct of Swift's *copy-in copy-out* memory model for `inout` parameters. The value is copied into the function, and upon the function's return, the potentially mutated value is written back to the original declaration, triggering the standard assignment observation cycle.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Swift Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
