我有一个扩展名:
public extension UIWindow {
override public func topMostController()->UIViewController? { ... }
}
但是对于我的topMostController
,我收到下一个错误:
Declarations in extensions cannot override yet error
它适用于 Swift 3.1,但对于 Swift 4,我收到此错误。如何修复?他们在 Swift 4 中做了什么变化?
如果您将基本实现@objc
,它将起作用。有关内部结构的详细解释,请参阅Hamish的回答。
重写扩展中声明的方法有点棘手。Objective-C支持它,但它不是绝对安全的。Swift 的目标是做得更好。该提案尚未完成。
此处提供提案的当前版本。
扩展可以向类型添加新功能,但不能重写现有功能。
扩展向现有类、结构、枚举或协议类型添加新功能。这包括扩展您无权访问原始源代码的类型的功能(称为追溯建模(。
Swift 中的扩展可以:
- 添加计算实例属性和计算类型属性
- 定义实例方法和类型方法
- 提供新的初始值设定项
- 定义下标
- 定义和使用新的嵌套类型
- 使现有类型符合协议
苹果开发者指南
您尝试执行的操作类似于此代码所做的操作:
class MyClass: UIWindow {
func myFunc() {}
}
extension MyClass {
override func myFunc() {}
}
注意:如果要override topMostController()
则使子类为UIWindow
Swift 5
实际上OP代码中几乎没有问题:
UIView
(这是UIWindow
的超类(没有方法topMostController()
,这就是为什么你不能覆盖它。苹果不鼓励
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()
}
}