4

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
  • 314,917
  • 42
  • 532
  • 579
user1107173
  • 10,334
  • 16
  • 72
  • 117
  • 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

2 Answers2

11
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
  • 777
  • 6
  • 24
0
protocol Test {
    var aValue: CGFloat {get set}
}

extension Test {
//    var aValue: CGFloat {
//        return 0.3
//    }
    var aValue: CGFloat {
        get {
            return 0.3
        }
        set {
            debugPrint("new value is \(aValue)")
        }
    }
}

struct TestClass: Test {
        
    func printData() {
        debugPrint(aValue)
    }
}

let aTestClass = TestClass()
aTestClass.printData()
CrazyPro007
  • 1,006
  • 9
  • 15