Skip to content
AgileLogics
6 min read

Properties: Stored, Computed, and Observed

Prerequisites: Structs

Swift types can have several kinds of properties.

Stored properties with defaults

struct Settings {
    var fontSize = 14
    var theme = "light"
}

let defaults = Settings()
let custom = Settings(fontSize: 18)
print(defaults.fontSize, custom.fontSize, custom.theme)
14 18 light

Properties with default values can be left out of the memberwise initializer.

Computed properties

A computed property doesn't store a value — it calculates one each time it's read:

struct Rectangle {
    var width: Double
    var height: Double

    var area: Double {
        width * height
    }

    var isSquare: Bool {
        width == height
    }
}

var rect = Rectangle(width: 4, height: 5)
print(rect.area)
rect.width = 5
print(rect.area, rect.isSquare)
20.0
25.0 true

area is always correct, because it's recalculated from the current width and height — there's no stored copy to forget to update.

Property observers

didSet runs code after a stored property changes; willSet runs just before:

struct Thermostat {
    var target = 20 {
        didSet {
            print("Target changed from \(oldValue) to \(target)")
        }
    }
}

var home = Thermostat()
home.target = 22
print(home.target)
Target changed from 20 to 22
22

oldValue is available inside didSet; newValue inside willSet.

Type properties

static properties belong to the type itself, shared by all instances:

struct Temperature {
    static let freezingPoint = 0.0
    var celsius: Double
}

print(Temperature.freezingPoint)
0.0

Lazy properties

A lazy var isn't created until it's first used — useful for expensive values that may never be needed:

struct Report {
    lazy var summary: String = {
        print("Building summary...")
        return "12 sales"
    }()
}

var report = Report()
print("Report created")
print(report.summary)
print(report.summary)
Report created
Building summary...
12 sales
12 sales

Common mistakes

  • Storing a value that could be computed (for example, storing area alongside width and height), then forgetting to update it.
  • Doing slow work inside a computed property that's read often.