我有一个扩展名:
public extension UIWindow {
override public func topMostController()->UIViewController? { ... }
}
但对于我的topMostController
,我收到了下一个错误:
Declarations in extensions cannot override yet error
它适用于Swift 3.1,但对于Swift 4,我收到此错误。怎么修好?他们在Swift 4中有什么变化?
答案 0 :(得分:64)
如果您进行基本实现@objc
,它将起作用。有关内部结构的详细说明,请参阅Hamish's answer。
在扩展中声明的重写方法有点难以正确执行。 Objective-C支持它,但它不是绝对安全的。斯威夫特的目标是做得更好。该提案尚未完成。
提案的当前版本here。
答案 1 :(得分:12)
扩展程序可以为类型添加新功能,但它们无法覆盖现有功能。
扩展为现有的类,结构,枚举或协议类型添加新功能。这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模)。
Swift中的扩展程序可以:
您尝试执行的操作类似于此代码所做的操作:
class MyClass: UIWindow {
func myFunc() {}
}
extension MyClass {
override func myFunc() {}
}
注意:如果您想要override topMostController()
,请创建UIWindow
答案 2 :(得分:0)
实际上,OP代码中的问题很少:
UIView
(是UIWindow
的超类)没有方法topMostController()
,这就是为什么您不能覆盖它的原因。
Apple 不鼓励 override func
内的extension
:
扩展可以为类型添加新功能,但不能 覆盖现有功能。
如果您仍然想覆盖扩展中的功能,有两种方法:
[A] 在父类中用@objc dynamic func
标记您的函数:
class Vehicle {
@objc dynamic func run() { /* do something */ }
}
class Car: Vehicle { }
extension Car {
override func run() { /* do another thing */ }
}
[B] 覆盖内置类的功能,该内置类是NSObject
的后代。
extension UIWindow {
// UIWindow is a descendant of NSObject, and its superclass UIView has this function then you can override
override open func becomeFirstResponder() -> Bool {
...
return super.becomeFirstResponder()
}
}