简体   繁体   中英

Can we use willSet and didSet with getter and setter?

I was reading about willset and didset of properties in swift I came to know that I can use these with variable having initial value like below:

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

property = "anothername"

so can I use willget and didset like below:

var property2:String{

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}

it gives me this error:

non-member observing properties require an initializer
var property2:String{
    ^

so anyone can explain me what is going on here and can I use getter and setter with willset and didset together like:

var property2:String{

    get{return property2}
    set{propert2 = newValue}

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}

The error that says you lack an initializer can be solved by giving the property a default value like your first piece of code did:

var property2:String = "Some default value"{

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}

Now I will answer why can't you use property observers on computed properties.

Because there is no point.

For a settable computed property, you already have the setter, so you can write whatever code you want to execute when the value is set in the setter . Why do you need an extra willSet or didSet ? And for a get-only computed property, it can't be set so when do you expect willSet and didSet to be executed?

Basically, the set block in computed properties already fulfils the purpose of willSet and didSet . Everything you write in willSet you can write it in set before you set the value. Everything you write in didSet you can write in set after you set the value.

Also, note that your third code can cause a Stack Overflow since you are accessing property2 inside its own getter and setting it inside its own setter.

  • First issue (second snippet) :

    The property / member doesn't have an initial value, that's what the error message says, you need to write an initializer or assign an initial value like in the first snippet. The error is not related to the observers.

  • Second issue (third snippet) :

    Property observers in computed properties are not allowed . Your example without the observers doesn't work anyway (assuming propert2 is a typo and you mean property2 ). The setter will cause an infinite loop because it's calling itself.

From Apple Doc Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.

so you can solve this by adding ? var property2:String?{

var property2:String?{

    willSet
    {
        print("value is about to change")
    }
    didSet
    {
        print("value is changes")
    }
}

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