扩展中的声明不能覆盖 Swift 4 中的错误



我有一个扩展名:

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

代码中几乎没有问题:

  1. UIView(这是UIWindow的超类(没有方法topMostController(),这就是为什么你不能覆盖它。

  2. 苹果不鼓励override func内部extension

    扩展可以向类型添加新功能,但不能 覆盖现有功能。

  3. 如果您仍然想覆盖扩展中的函数,有两种方法:

[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()
    }
 }

最新更新