3

I am trying to provide a default value for a variable in a Protocol. I am getting an error:

Type ViewController does not conform to protocol Test

Code:

protocol Test {
    var aValue: CGFloat { get set }
}

extension Test {
    var aValue: CGFloat {
        return 0.3
    }
}


class ViewController: UIViewController, Test {

    override func viewDidLoad() {
       super.viewDidLoad()
       print("value \(aValue)")
    }
}

How can I provide a default value so the ViewController can use the default value (in the protocol extension) without to declaring it?

rmaddy
  • 307,833
  • 40
  • 508
  • 550
user1107173
  • 9,626
  • 14
  • 67
  • 111
  • 1
    The extension hasn't implemented the `set` method for the value as stated in the protocol declaration - will implementing this (or removing the `set` capability) fix the problem? – Chris Shaw Apr 17 '19 at 23:13
  • I would like to be able to set the value (override the default). How will the `set` look like? – user1107173 Apr 17 '19 at 23:16
  • That depends on what you want the default `set` to do. The default `get` returns 0.3, so should the default `set` override this (in which case, it's probably best to just implement with a variable) or should it be ignored? – Chris Shaw Apr 17 '19 at 23:19
  • Yes, I would like the option to be able to override the default value. Thanks. – user1107173 Apr 17 '19 at 23:20
  • Then refer to this answer for some ways around it (https://stackoverflow.com/a/38885813/8903497). You can't have stored properties in a protocol (or extension to protocol) so you'll have to find another way. – Chris Shaw Apr 17 '19 at 23:30

1 Answers1

8
protocol Test {
    var aValue: CGFloat { get set }
}

extension Test {
    var aValue: CGFloat {
        get {
            return 0.3
        }
        set {
            print("the new value is \(newValue)")
        }
    }
}

class Default: Test {
    init() {
        print("value \(aValue)")
    }
}


class ViewController: Test {

    var aValue: CGFloat {
        get {
            return 0.4
        }
        set {
            print("i am overriding the setter")
        }
    }

    init() {
        print("value \(aValue)")
    }
}

var d = Default() // value 0.3
d.aValue = 1 // the new value is 1.0

var vc = ViewController() // value 0.4
vc.aValue = 1 // i am overriding the setter

Since you have a protocol extension, you don't have to implement neither the getter nor the setter if you don't want to.

https://docs.swift.org/swift-book/LanguageGuide/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID259

In addition to stored properties, classes, structures, and enumerations can define computed properties, which do not actually store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.

You can't set the value of the same variable in the setter itself.

Huy-Anh Hoang
  • 716
  • 5
  • 22