简体   繁体   中英

Swift can lazy and didSet set together

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?

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

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
    }
}

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.

Yes, Started by version Swift 5.3 Property observers can now be attached to lazy properties.https://www.swiftbysundell.com/tips/lazy-property-observers/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM