我们可以将 willSet 和 didSet 与 getter 和 setter 一起使用吗?

Dev*_*der 7 properties getter-setter swift

我正在阅读有关 swift 属性的 willset 和 didset 我开始知道我可以将这些与具有初始值的变量一起使用,如下所示:

var property = "name"
{
    willSet
    {
        print("property is about to changed")
    }
    didSet
    {
        if property == oldValue
        {
            print("values are same")
        }
        else
        {
            print("value changed")
        }
    }
}

property = "anothername"
Run Code Online (Sandbox Code Playgroud)

那么我可以像下面这样使用 willget 和 didset 吗:

var property2:String{

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}
Run Code Online (Sandbox Code Playgroud)

它给了我这个错误:

non-member observing properties require an initializer
var property2:String{
    ^
Run Code Online (Sandbox Code Playgroud)

所以任何人都可以向我解释这里发生了什么,我可以将 getter 和 setter 与 willset 和 didset 一起使用,例如:

var property2:String{

    get{return property2}
    set{propert2 = newValue}

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}
Run Code Online (Sandbox Code Playgroud)

Swe*_*per 10

可以通过为该属性提供一个默认值来解决缺少初始化程序的错误,就像您的第一段代码所做的那样:

var property2:String = "Some default value"{

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我将回答为什么你不能在计算属性上使用属性观察器。

因为没有意义。

对于可设置的计算属性,您已经有了 setter,因此您可以编写在 setter 中设置值时要执行的任何代码。为什么你需要一个额外的willSetdidSet?而对于一个GET-只计算属性,不能设置,所以当你期望willSetdidSet被执行?

基本上,set计算属性中的块已经实现了willSet和的目的didSet。您写入的所有内容都willSet可以在set设置值之前写入。写入的所有内容都didSet可以在set设置值后写入。

另外,请注意,您的第三个代码可能会导致堆栈溢出,因为您正在访问property2其自己的 getter 并将其设置在其自己的 setter 中。


Abd*_*ish -2

来自 Apple Doc 类和结构必须在创建该类或结构的实例时将其所有存储的属性设置为适当的初始值。存储的属性不能处于不确定状态。

所以你可以通过添加 ? 来解决这个问题 var property2:字符串?{

var property2:String?{

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 无意冒犯,但可选的作为缺少的初始化程序的替代品是最糟糕的建议。 (4认同)