扩展中的声明无法覆盖Swift 4中的错误

时间:2017-06-18 15:09:56

标签: ios swift swift-playground swift4

我有一个扩展名:

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

但对于我的topMostController,我收到了下一个错误:

Declarations in extensions cannot override yet error

它适用于Swift 3.1,但对于Swift 4,我收到此错误。怎么修好?他们在Swift 4中有什么变化?

3 个答案:

答案 0 :(得分:64)

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

在扩展中声明的重写方法有点难以正确执行。 Objective-C支持它,但它不是绝对安全的。斯威夫特的目标是做得更好。该提案尚未完成。

提案的当前版本here

答案 1 :(得分:12)

扩展程序可以为类型添加新功能,但它们无法覆盖现有功能。

  
    

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

  

Swift中的扩展程序可以:

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

Apple Developer Guide

您尝试执行的操作类似于此代码所做的操作:

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

extension MyClass {
    override func myFunc() {}
}

注意:如果您想要override topMostController(),请创建UIWindow

的子类

答案 2 :(得分:0)

Swift 5.0

实际上,OP代码中的问题很少:

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

  2. Apple 不鼓励 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()
    }
 }