Optional protocol method/property confusion

Was researching on protocols with optional methods/properties, and a bit confused with compiler behavior.

In my understanding last line in provided code should not be reported as error, because BaseClass implements ProtocolWithOptionals, and so, can have "name" property.

Still I'm not sure if it is a bug, or just my wrong understanding.

Would be glad to hear thoughts from others before reporting as bug to Apple.


@objc protocol ProtocolWithOptionals: NSObjectProtocol {
  @objc optional var name: String { get }
}

class BaseClass: NSObject, ProtocolWithOptionals { }

class ChildClass: BaseClass {
  var name: String { return "ChildClass" }
}

let childClass: BaseClass = ChildClass()

print((childClass as ProtocolWithOptionals).name)  // works fine

print(childClass.name) //ERROR: Value of type 'BaseClass' has no member 'name'

Replies

If you declare


let childClass: ChildClass = ChildClass()

then error goes away.


Similarly, if you declare name in BaseClass (and override in Child), it works (you can remove the optional)


class BaseClass: NSObject, ProtocolWithOptionals {
    var name: String { return "BaseClass" }
}

class ChildClass: BaseClass {
    override var name: String { return "ChildClass" }
}


Or, if you keep

let childClass: BaseClass = ChildClass()


and write

print((childClass as! ChildClass).name) // NO ERROR: Value of type 'ChildClass' has member 'name'


No error.



So the logic:

- you declared var name as optional

- you did not include in BaseClass: property does not exist here ; it will only be create in ChildClass

- You declare childClass as

let childClass: BaseClass = ChildClass()


So the property is not known from compiler (even though it exists, as proves print((childClass as! ChildClass).name))


I don't think this is a bug:

- error is detected at compilation

- even if could be "OK" at execution.

In fact, it is a good thing: it reminds you that you did not define the property in BaseClass, so you should not use it !

Hi! Thank you for response!
It is definitely clear how to avoid such situation. Still in my mind Protocol itself "defines" the property, and so, compiler should know about it.

One more point: autosuggest "knows" about this property in BaseClass