Swift可以懒惰和didSet组合在一起

时间:2015-12-23 01:19:33

标签: swift

我有一个属性

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

我想添加didSet方法,是否可能?

3 个答案:

答案 0 :(得分:17)

简答:不。

在你的某些类或方法中尝试这个简单的例子:

lazy var myLazyVar: Int = {
    return 1
} () {
    willSet {
        print("About to set lazy var!")
    }
}

这会给您以下编译时错误:

  

懒惰的属性可能没有观察者。

关于另一个答案中的let语句:lazy变量不是必需的只是“让常量延迟初始化”。请考虑以下示例:

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

答案 1 :(得分:6)

简短的回答正如其他人所说的那样是" no"但是有一种方法可以使用内部隐藏的懒惰变量和计算变量来获得效果。

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

答案 2 :(得分:3)

points是一个常量,你不能设置任何东西。与let常量的唯一区别在于它(可能)稍后进行初始化。

This answer提供了有关在var案例中使用let代替lazy的原因的更多信息。

编辑:使答案看起来不是空的 请查看this blog post,其中作者提出了一些有关为什么观察lazy vars可能不支持 的有效点。 oldValue在观察者中应该是什么? nil?在你的非选择性案例中,这不是一个好主意。