A getter in Swift allows access to a property, and a setter allows a property to be set. This post presents an overview of getters and setters, and examples of some Swift features related to getters and setters:
Automatically Generated Getters and Setters
get Getter
a. get throws (new in Swift 5.5)
set Setter
willSet
didSet
a. ‘didSet’ cannot be provided together with a getter
b. ‘willSet’ cannot be provided together with a getter
c. ‘didSet’ cannot be provided together with a setter
d. ‘willSet’ cannot be provided together with a setter
Contents
FREE all Swift Loading Animations
Immediately get access to commented code for these animations when you follow Advanced Swift.
Automatically Generated Getters and Setters
When an instance property is defined in Swift using var, a getter and setter is automatically generated:
class Notes {
var canSave = false
}
notes = Notes()
notes.canSave // Getter is available
notes.canSave = true // Setter is available
When an instance property is defined in Swift using let, only a getter is available:
class Store {
let canOrder = false
}
store = Store()
store.canOrder // Getter is available
// This will not compile and cause the error:
// “Cannot assign to property ‘canSave’
// is a ‘let’ constant”
store.canOrder = true
get Getter
One way to implement a variable property without an exposed setter is to indicate a variable as private(set):
class Store {
private(set) var canOrder = false
}
// Create a store instance
store = Store()
store.canOrder // Getter is available
// This will not compile and cause the error:
// “Cannot assign to property: ‘canOrder’
// setter is inaccessible”
store.canOrder = true
Another way to implement a variable property without an exposed setter is to use get. Often get is used to expose a getter to a private property:
class Store {
private var _canOrder = false
var canOrder: Bool {
get { return _canOrder }
}
}
// Create a store instance
store = Store()
store.canOrder // Getter is available
// This will not compile and cause the error:
// “Cannot assign to property: ‘canOrder’
// is a get-only property”
store.canOrder = true
get throws (new in Swift 5.5)
Starting in Swift 5.5, throws is available for getters defined with get:
class Notes {
func isDatabaseAvailable() throws -> Bool {
/* … */
}
var canSave: Bool {
get throws {
return try isDatabaseAvailable()
}
}
}
notes = Notes()
do {
if try notes.canSave {
// Handle logic
}
}
catch {
// Handle error
}
set Setter
The set keyword can be used to implement an explicit setter in Swift. Often set is used to expose a setter for a private property and apply additional logic:
class Notes {
func isDatabaseAvailable() -> Bool {
/* … */
}
private var _canSave = false
var canSave: Bool {
get { return _canSave }
set {
if isDatabaseAvailable() {
_canSave = newValue
}
}
}
}
willSet
If explicit getters and setters using get and set are not defined, willSet can be used to take action before a new value is set for a property:
class Notes {
func storePreviousSaveValue(_ canSave: Bool) {}
var canSave = false {
willSet {
// Inside of willSet, the property
// canSave will be the old value,
// before a new one is set
storePreviousSaveValue(canSave)
}
}
}
// Creates an instance of notes with
// notes.canSave initialized to false
notes = Notes()
// willSet will be called while notes.canSave is
// false, so storePreviousSaveValue is called
// with false, then notes.canSave is set to true
notes.canSave = true
didSet
If explicit getters and setters using get and set are not defined, didSet can be used to take action after a new value is set for a property:
class Notes {
@IBOutlet var saveButton: UIButton?
var canSave = false {
didSet {
// Inside of didSet, the property
// canSave will have the new value
saveButton?.userInteractionEnabled = canSave
}
}
}
// Creates an instance of notes with
// notes.canSave initialized to false
notes = Notes()
// didSet will be called after notes.canSave is
// set to true, so saveButton?.userInteractionEnabled
// will be set to true
notes.canSave = true
‘didSet’ cannot be provided together with a getter
If only didSet and get are implemented, didSet will never be called because a get-only property cannot be set:
var canSave: Bool {
// This causes the compiler error:
// “‘didSet’ cannot be provided
// together with a getter”
get { /* … */ }
didSet { /* … */ }
}
‘willSet’ cannot be provided together with a getter
If only willSet and get are implemented, willSet will never be called because a get-only property cannot be set:
var canSave: Bool {
// This causes a compiler error:
// “‘willSet’ cannot be provided
// together with a getter”
get { /* … */ }
willSet { /* … */ }
}
‘didSet’ cannot be provided together with a setter
If only didSet and set are implemented, didSet should instead be implemented inside of the set setter:
var canSave: Bool {
// This causes a compiler error:
// “‘didSet’ cannot be provided
// together with a setter”
set { /* … */ }
didSet { /* … */ }
}
// This is a better alternative:
var canSave: Bool {
set {
canSave = newValue
// Add code for didSet here,
// after a new value is set
}
}
‘willSet’ cannot be provided together with a setter
If only willSet and set are implemented, willSet should instead be implemented inside of the set setter:
var canSave: Bool {
// This causes a compiler error:
// “‘willSet’ cannot be provided
// together with a setter”
set { /* … */ }
willSet { /* … */ }
}
// This is a better alternative:
var canSave: Bool {
set {
// Add code for willSet here,
// before a new value is set
canSave = newValue
}
}
Swift Getters and Setters
That’s it! By using get, set, willSet, and didSet you can implement getters and setters in Swift.
Permanent link to this post here
