Skip to content

Commit 45c9ae6

Browse files
authored
Clarify property observer behavior during initialization (#370)
The first sentence on superclass behavior is true, but the final sentence on same-class behavior is misleading. Property observers are not triggered regardless of whether the superclass initializer has been called or not. However, a mutating function called from the initializer _does_ trigger property observers. Personally I think this is counterintuitive, the topic has been discussed in the Swift Forum [1] and would probably be a headache for the compiler and isn't going to change anyway (in order to preserve the semantics of existing code). But the fact remains that the superclass initializer is a red herring in the final sentence. [1] https://forums.swift.org/t/14024/1 Tested with Xcode 16.3, Swift 6.1. ``` import Foundation class Ship { var crewSize: Int { willSet { print("Ship: willSet crewSize to", newValue) } didSet { print("Ship: didSet crewSize to", crewSize) } } init(crewSize: Int) { self.crewSize = crewSize } } class CargoShip: Ship { var cargoCapacity: Int { willSet { print("CargoShip: willSet cargoCapacity to", newValue) } didSet { print("CargoShip: didSet cargoCapacity to", cargoCapacity) } } init(cargoCapacity: Int, crewSize: Int) { self.cargoCapacity = cargoCapacity super.init(crewSize: crewSize) // Instance is now fully initialized. // Change a property in the superclass, property observers are called // as expected. self.crewSize += 5 // Change a property in the class after the superclass has been // initialized, property observers are not called (?) self.cargoCapacity += 20 // But call a function that changes a property in the class, property // observers are called (??) doubleCargoCapacity() } func doubleCargoCapacity() { cargoCapacity *= 2 } } let cargoShip = CargoShip(cargoCapacity: 10, crewSize: 5) // Ship: willSet crewSize to 10 // Ship: didSet crewSize to 10 // CargoShip: willSet cargoCapacity to 60 (triggered by doubleCargoCapacity) // CargoShip: didSet cargoCapacity to 60 (triggered by doubleCargoCapacity) ```
2 parents 93b2ebc + 8b0c758 commit 45c9ae6

File tree

2 files changed

+3
-3
lines changed

2 files changed

+3
-3
lines changed

TSPL.docc/LanguageGuide/Initialization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ or by assigning a default property value as part of the property's definition.
3131
These actions are described in the following sections.
3232

3333
> Note: When you assign a default value to a stored property,
34-
> or set its initial value within an initializer,
34+
> or set its value within an initializer,
3535
> the value of that property is set directly,
3636
> without calling any property observers.
3737

TSPL.docc/LanguageGuide/Properties.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,8 @@ the new value that you assign replaces the one that was just set.
736736
> Note: The `willSet` and `didSet` observers of superclass properties
737737
> are called when a property is set in a subclass initializer,
738738
> after the superclass initializer has been called.
739-
> They aren't called while a class is setting its own properties,
740-
> before the superclass initializer has been called.
739+
> They aren't called while a class is setting its own properties
740+
> in the body of the initializer.
741741
>
742742
> For more information about initializer delegation,
743743
> see <doc:Initialization#Initializer-Delegation-for-Value-Types>

0 commit comments

Comments
 (0)