Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable with getter/setter cannot have initial value, on overridden stored property

Tags:

swift

When creating a stored property with Observing Accessors, I can specify a default value. However, when overriding a stored property and its Accessors I cannot specify a default value.

Variable with getter/setter cannot have initial value.

Which seems very strange, as this is NOT a computed property with a getter/setter, but a set of Observing Accessors on a stored property!

class FirstViewController: UIViewController {

internal var test: Float = 32.0 {
    willSet {

    }

    didSet {

    }
}

The first view controller compiles fine, with a stored property initialized to 32.0

class SecondViewController: FirstViewController {

override var test: Float = 64.0 {
    willSet {

    }

    didSet {

    }
}

The second view controller does not compile, as the 'computed property' is being given an initial value

like image 689
J_llama Avatar asked Aug 10 '16 15:08

J_llama


People also ask

Can we override stored property in Swift?

You can provide a custom getter (and setter, if appropriate) to override any inherited property, regardless of whether the inherited property is implemented as a stored or computed property at source.

What is the difference between a computed property and a property set to a closure?

A property defined with a closure is defined once and stored to that variable. A computed property acts like a function, and in the example above will return a new CAGradientLayer object.

What is getter and setter in Swift?

Setters and getters in Swift apply to computed properties/variables. These properties/variables are not actually stored in memory, but rather computed based on the value of stored properties/variables. See Apple's Swift documentation on the subject: Swift Variable Declarations.

What is stored property and computed property in Swift?

Stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value. Computed properties are provided by classes, structures, and enumerations.


2 Answers

In swift you are able to override properties only with computed properties (which are not able to have default values) with same type. In your case, if you wish override test property in SecondViewController you need write something like this:

override var test: Float {
    get {
        return super.test
    }
    set {
        super.test = newValue
    }
}

And there is no way to override didSet/willSet observers directly; you may do this by write other methods invoked in observers and just override them:

FirstViewController:

internal var test: Float = 32.0 {
    willSet {
        test_WillSet(newValue)
    }
    didSet {
        test_DidSet(oldValue)
    }
}

func test_WillSet(newValue: Float) {}
func test_DidSet(oldValue: Float) {}

SecondViewController:

override func test_WillSet(newValue: Float) {
    super.test_WillSet(newValue)
}
override func test_DidSet(oldValue: Float) {
    super.test_DidSet(oldValue)
}
like image 56
Shadow Of Avatar answered Sep 22 '22 04:09

Shadow Of


I know that this has been asked a long time ago but I came up with a slightly different solution and it works exactly as you wanted. You have a property in the first ViewController then in the inherited one you override it and have observers set on it in the form of didSet.

So in the FirstViewController you have a property like in the example below:

var myNumber: Double = 20.00

Then in the SecondViewController which inherits from FirstViewController you override it as follows:

override var myNumber: Double {
     didSet {
             //Here you can update UI or whatever you want to do once the property changes
             //Print its value
             print("Value of myNumber is : \(myNumber)")
            }

I hope this will help someone with the above issue as this is a nice and easy way to solve the problem mentioned above.

like image 22
AD Progress Avatar answered Sep 22 '22 04:09

AD Progress