Kind of nerd question. It's unclear to me, what exactly makes this code works:
class Shape { }
extension Shape {
@objc func redraw() {
print("from ext")
}
}
class Circle: Shape { }
class Line: Shape {
override func redraw() { // Compiler error: Declarations from extensions cannot be overridden yet
print("from subclass")
}
}
let line = Line()
let shape:Shape = line
let circle = Circle()
line.redraw() //from subclass
circle.redraw() //from ext
shape.redraw() //from subclass
If I omit @objc
keyword in extension, the code won't compile - it's expected behaviour since methods in extension use static method dispatch -> cannot be overridden.
But why adding @objc
makes it work? According to documentation and most articles, all is @objc
doing is making things visible to Objective-c runtime. To change method dispatch type there is a special keyword - dynamic
. But seems it is not necessary here!
Help me figure out, why is adding @objc
(and omitting dynamic
) makes such things possible.