Properties in Swift
Hi there!! welcome back to tiny read on swift properties.
Properties makes your programming easier and reduce amount of code. Store property provided by only class and structure. You can use property observer to monitor value changes of instance variable. Also, you can use properties wrappers in terms of code reusability.
Stored Properties:
It is a constant or variable that is stored some value as part of an instance variable. These properties you usually would be using to show some content on screen or some manipulation purpose.
Ex. for model class person has name property which hold value to show on screen.
class Person {
let name = "John" // this store has some value.
}
As “name” is constant, so space has been reserved at compile time only. You could consider this as a container (Mug) that hold tea (as a value). if you want to have a tea (value), pick up container and have it.
Lazy Stored Properties:
Lazy store property whose initial value is not calculated until first time used or called.
Constant cannot be declared as lazy property as its value is already calculated.
As this property been initialized on called, it will not allocate space in memory.
Ex.
lazy var backgroundView: UIView = { in
let view = UIView()
view.backgroundColor = .red
return view
}()
// if any code uses a backgroundView object that time it gets initialized.
// view.addSubView(backgroundView) - Now backgroudView comes into picture.
Global constants and variables are always computed lazily. they don’t need to be marked as lazy. Local constants and variables are never computed lazily.
Stored type properties are lazily initialized on their first access. They are guaranteed to be initialized only once so they do not need to be marked with the lazy modifier.
Computed Properties:
Do not actually store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.
Unlike store properties computed properties gives some other value per performing some operation/calculation.
You could consider computed property as a function.
var a = 5
var b = 10
var total: Int {
return a * b
}
print("Total: \(total)") // Total: 50
If you declare “total” as store variable and save addition 5*10= 50 then you have to additionally assign that value total = 50 which is static or hardcoding kind of thing.
Now if you update “a” and “b” values to 10 and 20, again you need to save result “200” as total = 200 i.e. kind of static assignment.
To make these dynamic “Computed” variable used with some operation in it.
Read-Only Computed Properties:
A computed property with a getter but no setter is known as a read-only computed property.
var pi: Double {
get { return 3.14}
}
You can’t set some value here i.e. two = 3 give compile time error. You could just use them to get available value from them.
Property Observers:
Property observers observe and respond to changes in a property’s value. they called when a new value or the same value set.
They cannot add to lazy property.
Consider they are like triggers.
Ex. 1. willSet (called just before the value is stored.),
var noOfPerson = 0 {
willSet {
print("value before store: \(noOfPerson)") // value before store: 0
print("new value going to store: \(newValue)") // new value going to store: 1
if noOfPerson == 0 {
// There was no person in office.
}
}
}
noOfPerson = 1 // this will print above two log from willSet and noOfPerson = 1 now.
In above case, if you want to perform some check before value change from “0” to “1”
Ex. do something if noOfPerson is zero and before change this to some other value (Only execute if value getting set from “0” to some other value).
2. didSet(called after value stored).
This triggers as soon as some value is been set.
var name = "John" {
didSet {
updateUI?() // Update UI when new value set
}
}
name = "Rob" // this will call updateUI closure
You could show whatever value has been set to “name” property in code to user interface like label or textView as many time you set “name”.
//In you view/viewController
//On main thread
func updateUI() {
labelPerson.text = name
// Or you could even call to table reloadData() method.
}
Otherwise, without didSet you would have to write button action method to update “name” value to user interface. And required to tap on button to see if update in “name” value to reflect in UI.
@IBAction func buttonTapped(_ sender: UIButton) {
labelPerson.text = viewModel.name
}
You might used completeHandler callback to update your UI right? same way you could you didSet event to update your UI base on some conditions.
Property Wrappers:
It allows us to set stored property based on some condition. We write code once and reuse it.
Ex. You want to set max speed 80 for all cars.
@propertyWrapper
struct MaxCarSpeed {
private var number: Int
init() {
self.number = 0
}
var wrappedValue: Int {
get { return number }
set { number = min(newValue, 80) } // Max speed can be set to 80
}
}
struct BMWCar {
@MaxCarSpeed var topSpeed: Int // Use of property wrapper
}
var car1 = BMWCar()
print(car1.topSpeed)
// Prints "0"
car1.topSpeed = 10
print(car1.topSpeed)
// Prints "10"
car1.topSpeed = 100// Trying to set max value but property wrapper reset to 80.
print(car1.topSpeed)
// Prints "80"
Property wrapper allows you to set max value to some defined value or less than that (in above case).
Summary:
Store properties hold some data.
Lazy properties initialized when called first time.
Computed properties do some calculation and returns result, but no storage.
Read-only properties are just getter.
Property observers are triggers before/after setting new value.
Property wrappers are adding some constraint on setting some value.
Please do clap if this adds some value and see you another time.
Stackademic 🎓
Thank you for reading until the end. Before you go:
- Please consider clapping and following the writer! 👏
- Follow us X | LinkedIn | YouTube | Discord
- Visit our other platforms: In Plain English | CoFeed | Venture | Cubed
- More content at Stackademic.com