Site icon DataFlair

Swift Properties and Its Types

swift properties

Placement-ready Courses: Enroll Now, Thank us Later!

We use properties in Swift to encapsulate and manage values that are associated with enumerations, structures and classes. We can store and compute properties in Swift. In this article, we’ll learn about different kinds of properties in Swift. We’ll understand when and how to use them with the help of examples.

Swift Stored Property

When we store a value as a constant or a variable as an instance in a class or structure, we call it a stored property. There can be 2 types, namely, variable stored property and constant stored property.

For example,

struct Example{
    var variableStoredProperty: String
    var constantStoredProperty: String
}

var example = Example(variableStoredProperty: "DataFlair", constantStoredProperty: "DataFlair")

example.variableStoredProperty = "Properties"

print("Variable Stored Property: \(example.variableStoredProperty)")
print("Constant Stored Property: \(example.constantStoredProperty)")

Output:

Variable Stored Property: Properties
Constant Stored Property: DataFlair

Note that if we declare the instance of a structure or class as a constant, then we cannot change the value of a variable stored property.

Swift Lazy Stored Property

The properties where we do not calculate initial values until we access them for the first time are called lazy stored properties in Swift. These do not occupy any memory until we access them for the first time. These can be useful when we have complex and expensive calculations.

We also use them when the value of the property depends on other factors and are calculated when those factors are available. Note that we can declare a variable as a lazy property only. Since constant properties need to have a value before the initialization completes, we cannot declare it as lazy. We declare a property as lazy by writing the keyword lazy before the property declaration.

For example,

struct Circle{
    let radius: Double
    //circumference property is declared as lazy stored property
    lazy var circumference: Double = {
        return 2 * Double.pi * self.radius
    }()
    
    init(radius: Double){
        self.radius = radius
    }
}

var circleExample = Circle(radius: 5.0)
//When we access the circumference property for the first time here, it is initialized.
print("Circumference: \(circleExample.circumference)")

Output:

Circumference: 31.41592653589793

Note that there is no guarantee that a property declared with the lazy modifier will only be initialized once if it is accessed by several threads at once while the property is not yet initialized.

Swift Computed Property

Computed properties are the properties that do not store any value. Instead, it has a getter and an optional setter that computes value when accessed.

For example,

struct Temperature{
    var celsiusTemp: Double
    
    var fahrenheitTemp: Double{
        get {
            return (celsiusTemp * 9.0 / 5.0) + 32.0
        } set {
            celsiusTemp = (newValue - 32.0) * 5.0 / 9.0
        }
    }
    
    init(celsiusTemp: Double){
        self.celsiusTemp = celsiusTemp
    }
}
var temperature = Temperature(celsiusTemp: 32.0)
print("Temperature in Celsius: \(temperature.celsiusTemp).")
//accessing the computed property using a getter
print("Temperature in Fahrenheit: \(temperature.fahrenheitTemp).")
//accessing the computed property using a setter
temperature.fahrenheitTemp = 98.0
print("Temperature in Fahrenheit: \(temperature.fahrenheitTemp).")
print("Temperature in Celsius: \(temperature.celsiusTemp).")

Output:

Temperature in Celsius: 32.0.
The temperature in Fahrenheit 89.6.
Temperature in Fahrenheit: 98.0.
The temperature in Celsius is 36.666666666666664.

Shorthand Getter Declaration

If the setter of a computed property doesn’t specify a name for the new value to be set, newValue is used by default. Omitting the return from a getter follows the same rules as followed by functions with implicit returns.

The distinction between Stored and Computed Property in Swift

Stored Property Computed Property
The value of the instance is stored. The value of the instance is calculated when accessed.
Supported by classes and structures only. Supported by classes, structures and enumerations

Read-only Computed Property in Swift

A Read-only computed property is a property with a getter but no setter. It always returns a value. We can access it using the dot syntax. We cannot change (set) the property to a different value.

As discussed above, the computed property can only be declared as a variable; the same applies here too. We use the var keyword to declare computed and read-only computed property.

For example,

struct Circle{
    var radius: Double
    //area is a computer property
    var area: Double {
        return Double.pi * radius * radius
    }
}

var circleExample = Circle(radius: 6.0)
//calling the computed property, the value is calculated in real-time.
print("Area: \(circleExample.area)")

Output:

Area: 113.09733552923255

Swift Property Observers

We can add property observers to check and notify if a property’s value is changing. These are called every time a property’s value is set. We can add property observers to stored properties and inherited stored and computed properties. We use overriding to add property observers to the inherited properties.

We can define either or both of the following observers on a property.

willSet –

called just before we store a value.

didSet –

called immediately after we store a new value.

We can pass the old value with a new parameter name or Swift provides a default parameter name oldValue.

The following example explains the usage of willSet and didSet.

class TemperatureMonitor {
    var temperature: Double = 0.0 {
        willSet(newTemperature) {
            print("Temperature changing to \(newTemperature)°C")
        }
        didSet {
            print("Temperature changed from \(oldValue)°C to \(temperature)°C")
        }
    }
}

var monitor = TemperatureMonitor()
monitor.temperature = 25.0

monitor.temperature = 32.0

Output:

Temperature changing to 25.0°C
Temperature changed from 0.0°C to 25.0°C
Temperature changing to 32.0°C
Temperature changed from 25.0°C to 32.0°C

Swift Property Wrappers

Property Wrappers in Swift add custom behavior to properties. It adds a layer between the code that manages the storing of a property and the code that defines the property. We write a management code while defining a wrapper, and then we reuse it by applying multiple properties to it. We can define these wrappers on a class, structure or enumeration, which defines a wrappedValue property.

We follow the following syntax to write a property wrapper.

@propertyWrapper
struct WrapperName{
    var wrappedVal: dataType
    init(wrappedVal: dataType){
        self.wrappedVal = wrappedVal
    }
}

Setting Initial Values for Wrapper Properties

Projecting a Value from a Property Wrappers

Swift Type Properties

Type properties in Swift are the properties that are shared among all the instances of a class or a structure. Swift generates only one copy of the properties for all the instances of a type created. We create a type property by using the static keyword.

Querying & Setting Type Properties

We use querying to get a value of the type property. We use the setting to set a value of the type property. We query and set the type property using the class name and dot syntax.

For example,

struct Company{
    //declaring a type property using the static keyword.
    static var name = "DataFlair"
    
    static func greet() -> String{
        return "Hello from \(name)"
    }
}
//Querying type property
print("Querying: \(Company.greet())")
//Setting type property
Company.name = "DataFlair!!"
print("Querying after setting: \(Company.greet())")

Output:

Querying: Hello from DataFlair
Querying after setting: Hello from DataFlair!!

Global and local variables in Swift

Conclusion

Properties access stored or computed values that are part of an instance or type. In this article, we have discussed different kinds of swift properties, such as stored and computed properties. We have understood read-only computed properties along with property observers and wrappers. We have also seen querying and setting type properties.

Exit mobile version