64

我有一个扩展:

public extension UIWindow {
    override public func topMostController()->UIViewController? { ... }
}

但对我来说,topMostController我得到下一个错误:

Declarations in extensions cannot override yet error

它适用于 Swift 3.1,但对于 Swift 4,我收到此错误。如何修复?他们在 Swift 4 中发生了什么变化?

4

3 回答 3

66

如果您进行基本实现,它将起作用@objc。有关内部结构的详细说明,请参阅Hamish 的回答

覆盖扩展中声明的方法要正确执行有点棘手。Objective-C 支持它,但它不是绝对安全的。Swift 的目标是做得更好。该提案尚未完成。

当前版本的提案可在此处获得。

于 2017-10-15T19:26:58.220 回答
12

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

扩展向现有的类、结构、枚举或协议类型添加新功能。这包括扩展您无法访问原始源代码的类型的能力(称为追溯建模)。

Swift 中的扩展可以:

  • 添加计算实例属性和计算类型属性
  • 定义实例方法和类型方法
  • 提供新的初始化器
  • 定义下标
  • 定义和使用新的嵌套类型
  • 使现有类型符合协议

苹果开发者指南

您尝试做的与此代码所做的类似:

class MyClass: UIWindow {
    func myFunc() {}
}

extension MyClass {
    override func myFunc() {}
}

注意:如果你想override topMostController()然后制作子类UIWindow

于 2017-08-02T10:09:19.727 回答
2

斯威夫特 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()
    }
 }
于 2019-05-10T03:52:05.770 回答