Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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")
    }
}
like image 759
Devil Decoder Avatar asked Aug 20 '17 09:08

Devil Decoder


People also ask

What is willSet and didSet in Swift?

willSet is called before the data is actually changed and it has a default constant newValue which shows the value that is going to be set. didSet is called right after the data is stored and it has a default constant oldValue which shows the previous value that is overwritten.

Is didSet called on init?

willSet and didSet observers are not called when a property is first initialized. They are only called when the property's value is set outside of an initialization context.

What is the use of didSet in Swift?

Swift's solution is property observers, which let you execute code whenever a property has changed. To make them work, we use either didSet to execute code when a property has just been set, or willSet to execute code before a property has been set.

Did set and will set example?

These blocks of code are guaranteed to run whenever you update the variable. Thus you do not have to pay attention to it yourself. willSet { print("Name will change now.") } didSet { print("Name was changed.")}


2 Answers

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.

like image 96
Sweeper Avatar answered Oct 19 '22 06:10

Sweeper


  • 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.

like image 38
vadian Avatar answered Oct 19 '22 05:10

vadian