class A: UIVIEwController { func doThing() { print("dothing super class") } overrIDe func vIEwDIDLoad() { print("vIEwdIDload superclass") super.vIEwDIDLoad() }}class B: A { }extension B { overrIDe func doThing() { print("dothing sub class") super.doThing() } overrIDe func vIEwDIDLoad() { print("vIEwdIDload subclass") super.vIEwDIDLoad() }}let a: A = B()a.doThing()let vc: UIVIEwController = B()vc.vIEwDIDLoad()
打印:
dothing super classvIEwdIDload subclassvIEwdIDload superclass
你可以看到,当它被转换为A时,它会跳过B的doThing的实现,但是当转换为UIVIEwController时,它包括vIEwDIDLoad的两个实现.这是预期的行为吗?如果是这样,这是什么原因?
ENV:Xcode 7.3,游乐场
解决方法 令人惊讶的是,编译器允许扩展中的覆盖.这不编译:class A { func doThing() { print("dothing super class") }}class B: A {}extension B { overrIDe func doThing() { // error: declarations in extensions cannot overrIDe yet print("dothing sub class") super.doThing() }}
在你的例子中,似乎编译器给你一个pass,因为A源自NSObject – 大概是为了允许这个类与Objective-C进行交互.这样做编译:
class A : NSObject { func doThing() { print("dothing super class") }}class B: A {}extension B { overrIDe func doThing() { print("dothing sub class") super.doThing() }}
我的猜测是,你被允许这样做的事实本身就可能是一个BUG. docs说:
Extensions can add new functionality to a type,but they cannot overrIDe existing functionality.
超越是没有被列为扩展可以做的事情之一.所以似乎这不应该编译.但是,如我之前所说,也许这是有意识的兼容Objective-C.无论哪种方式,我们正在探索一个边缘的情况,你非常好地引出了它的边缘.
特别地,上述代码仍然不会导致动态调度成为可 *** 作的.这就是为什么你必须声明doThing是动态的,如@jtbandes所建议的,或者将其放在实际的类而不是扩展名中 – 如果你想要多态 *** 作.因此,这可以按照你的期望工作:
class A : NSObject { dynamic func doThing() { print("dothing super class") }}class B: A {}extension B { overrIDe func doThing() { print("dothing sub class") super.doThing() }}
这样做也是如此:
class A : NSObject { func doThing() { print("dothing super class") }}class B: A { overrIDe func doThing() { print("dothing sub class") super.doThing() }}
我的结论是:非常好的例子将其提交给苹果作为可能的错误;不要这样做在课堂上超越,而不是延伸.
总结以上是内存溢出为你收集整理的ios – Swift在子类扩展中调度到覆盖的方法全部内容,希望文章能够帮你解决ios – Swift在子类扩展中调度到覆盖的方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)