Properties in Swift

Type properties and static keyword

Notes from the Apple Developer Documentation: The Swift Programming Language Guide on Properties

Stored vs. computed properties

Enums, classes, and structures — all can provide computed properties.

Only classes and structures can provide stored properties. Enums can’t.

Computed properties do not store a value.

Stored Properties

In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the varkeyword) or constant stored properties (introduced by the let keyword).

Lazy Properties

Lazy properties are useful when the initial value for a property is dependent on outside factors whose values are not known until after an instance’s initialization is complete. Lazy properties are also useful when the initial value for a property requires complex or computationally expensive setup that should not be performed unless or until it is needed.

For example, it is possible for a DataManager instance to manage its data without ever importing data from a file, so there is no need to create a new DataImporter instance when the DataManager itself is created. Instead, it makes more sense to create the DataImporter instance if and when it is first used.

NB: Lazy properties are NOT thread safe. If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property has not yet been initialized, there is no guarantee that the property will be initialized only once.

Computed Properties

Classes, structures, and enumerations can have computed properties.

Computed properties do not store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.

A computed property with a getter but no setter is known as a read-only computed property.

Property Observers

You have the option to define either or both of these observers on a property:

  • willSet is called just before the value is stored.
  • didSet is called immediately after the new value is stored.

Global and Local Variables

Global variables are variables that are defined outside of any function, method, closure, or type context. Local variables are variables that are defined within a function, method, or closure context.

Type Properties

Instance properties are properties that belong to an instance of a particular type. Every time you create a new instance of that type, it has its own set of property values, separate from any other instance.

Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time.

Stored type properties are lazily initialized on their first access. They are guaranteed to be initialized only once, even when accessed by multiple threads simultaneously, and they do not need to be marked with the lazy modifier.

Static keyword

Type properties are defined with the static keyword.

Type properties are queried and set with dot syntax, just like instance properties. However, type properties are queried and set on the type, not on an instance of that type.

Consider an example:

We define type properties url and session on an enum type MeetupAPI with the keyword static. We can then access those type properties with the dot syntax on the type itself as in:

print(MeetupAPI.url!)

However, try to remove the static keyword, and you’ll get a warning:

Warning: Enums may not contain stored properties

Stored property is a property that lives on a type that gets memory allocated to it. So a struct or a class can have stored properties.

Enums don’t fall under that, so they can only have computed properties on them.

Static var

A type property defined with the keyword static and as a variable stored property (called maxInputLevelForAllChannels) keeps track of the maximum input value that has been received by any AudioChannel instance.