Reputation: 16159
I have a property
public lazy var points: [(CGFloat,CGFloat,CGFloat)] = {
var pointsT = [(CGFloat,CGFloat,CGFloat)]()
let height = 100.0
for _ in 1...10 {
pointsT.append((someValue,someValue,100.0))
}
return pointsT
}()
And i want to add a didSet
method, is it possible?
Upvotes: 26
Views: 9618
Reputation: 61
Yes, Started by version Swift 5.3 Property observers can now be attached to lazy properties.
class C {
lazy var property: Int = 0 {
willSet { print("willSet called!") } // Okay
didSet { print("didSet called!") } // Okay
}
}
or
class C {
lazy var property: Int = { return 0 }() {
willSet { print("willSet called!") } // Okay
didSet { print("didSet called!") } // Okay
}
}
Please take a look at the links below for more:
Upvotes: 6
Reputation: 6504
The short answer is as other have said is "no" but there is a way to get the effect using a private lazy var and computed var.
private lazy var _username: String? = {
return loadUsername()
}()
var username: String? {
set {
// Do willSet stuff in here
if newValue != _username {
saveUsername(newValue)
}
// Don't forget to set the internal variable
_username = newValue
// Do didSet stuff here
// ...
}
get {
return _username
}
}
Upvotes: 9
Reputation: 57134
No
points
is a constant, you cannot set anything to it. The only difference to a let
constant is that it is (potentially) initialized later.
This answer provides a little more information as to why you use var
instead of let
in the lazy
case.
Edit: to make the answer not look to empty
Take a look at this blog post where the author raises a few valid points regarding why observing lazy
vars might not yet be supported. What should oldValue
be in the observer? nil
? That would not be a good idea in your non-optional case.
Upvotes: 3
Reputation: 73186
Short answer: no.
Try out this simple example in some class or method of yours:
lazy var myLazyVar: Int = {
return 1
} () {
willSet {
print("About to set lazy var!")
}
}
This gives you the following compile time error:
Lazy properties may not have observers.
With regard to the let
statement in the other answer: lazy variable are not necessary just "let constants with delayed initialisation". Consider the following example:
struct MyStruct {
var myInt = 1
mutating func increaseMyInt() {
myInt += 1
}
lazy var myLazyVar: Int = {
return self.myInt
} ()
}
var a = MyStruct()
print(a.myLazyVar) // 1
a.increaseMyInt()
print(a.myLazyVar) // 1: "initialiser" only called once, OK
a.myLazyVar += 1
print(a.myLazyVar) // 2: however we can still mutate the value
// directly if we so wishes
Upvotes: 27