Protocol extension doesn't seem to enforce variable in consumer?

Say you

protocol Able: class {
    var v:UIView? { get set }
    var x:CGFloat { get set }

then of course, when you use Able,

  • iOS: GPPSignInButton always asks for “Have offline access” Permission
  • failed to send the qLaunchSuccess packet
  • How to fetch images from photo library within range of two dates in iOS?
  • iOS 11 customise search bar in navigation bar
  • iOS / C: Algorithm to detect phonemes
  • Is there any way we can restrict duplicate entries in core data?
  • enter image description here

    if you forget “v” or “x”…

    it is an error. That’s good.

    So do this:

    class ScreenThing: UIViewController, Able {
        @IBOutlet var v: UIView?
        var x: CGFloat = 0.0

    All’s well. That’s great.

    It is enforced that you specify “v” and “x” and indeed initialize them.

    But. Try this…

    var _H: UInt8 = 0
    protocol Able: class {
    extension Able where Self:UIViewController {
        var p:P {
        get {
            return objc_getAssociatedObject(self, &_H) as! P
        set {
            objc_setAssociatedObject(self, &_H, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

    Able now has a property p.

    You can use p perfectly either in functions in Able, or, in functions in ScreenThing. That’s great.


    When you do this…..

    class ScreenThing: UIViewController, Able {

    you do not get an error.

    You can forget to initialize “p” (it will crash).

    Indeed you don’t have to specify “p” as a variable (as you must with “v” and “x”).

    Why is it so?

    This seems like a huge problem.

    Is there something different I have to do, to, make the compiler enforce “p”, just as it of course normally enforces variables in protocols?

    Another way to look at this question:

    Given exactly my code above:

    is there a way to enforce the compiler to need an initializer for “p” in the consumer class?

    For example.

    I tried this…

    class ScreenThing: UIViewController, Able {
        var p:P

    But that doesn’t work.

    (Strangely, that compiles – actually I don’t know what the hell it’s doing! It seems to be a “different” p from the p in the Extension. But in any event it doesn’t enforce the need for an initializer.)

    In short, again, is there something I could do or add, above, that would make the compiler enforce me initializing the pseudo-property-thing, just as of course it normally does when I put a property in the protocol such as “x” or “v”.


    • maybe I have to add some ordinary property in the protocol (like “pp”), and somehow make p related to that in some way?? Just a thought.

    (Footnote — see this to understand the “: class” needed in the protocol above.)

    Answering my own question:

    My confusion above is that there is nothing to initialize. The var p:P in the extension (with the get and set code blocks) is simply two functions.

    There’s nothing to initialize.

    So for example: in my extra question, I ask “how to force conforming classes initailize it on wake up?” That is meaningless. If anything, one could ask: “how to force conforming classes be sure to ‘use those functions’ on wake up?” – which has nothing to do with initialization.

    Note too that my specific example code in the computed variable, happens to (unrelatedly) use a variable that doesn’t get initialized – leading to confusion.

    Solutions Collect From Internet About “Protocol extension doesn't seem to enforce variable in consumer?”

    You don’t have to implement p in the protocol’s adopter, because the protocol extension has supplied an implementation. That is what a protocol extension is.

    Simpler example:

    protocol P {}
    extension P {
        func greet() {print("hello")}
    class C : P {}

    Note that (1) that compiles even though C does not declare greet and (2) it runs even though C does not contain an implementation of greet. That’s because that’s the job of the protocol extension.