【问题标题】:Overriding non-@objc declarations from extensions is not supported不支持从扩展覆盖非@objc 声明
【发布时间】:2019-03-27 04:48:40
【问题描述】:

我开始遇到与我经常使用的两个扩展函数相关的数百个错误。

我尝试注释掉出现此错误之前的所有新代码。我还尝试清理我的构建文件夹。我如何解决这篇文章标题中发现的错误?为什么在我成功使用这些扩展几个月后,它会随机出现?

extension UITableViewCell {

public func getSize(large: CGFloat, medium: CGFloat, small: CGFloat) -> CGFloat {
    var size = CGFloat()
    let screenHeight = Int(UIScreen.main.bounds.height)
    if screenHeight >= 800 {
        size = large
    } else if screenHeight >= 600 {
        size = medium
    } else {
        size = small
    }
    return size
}

public func formatPrice(_ price: Int) -> String {
    let lastDigit = price % 10
    var stringPrice = ""
    if lastDigit == 0 {
        stringPrice = "$\(Double(price) / 100)0"
    } else {
        stringPrice = "$\(Double(price) / 100)"
    }
    return stringPrice
}

}

【问题讨论】:

  • 你更新你的xcode版本了吗?你改变了 swift 版本吗?
  • 你能给我们reproducible example吗?将此代码放在一个空白项目中,它不会重现问题。所以找出你需要从你的项目中添加什么来显示问题。或者从另一个方向开始,复制你的项目并删除与问题无关的所有内容,直到你弄清楚需要什么来重现它。我能想到重现它的唯一方法是定义实现这两种方法的UITableViewCell 子类。但你会提到...
  • 我从 Xcode 11.6 升级到 12.0 时开始遇到这个问题。 Swift 4.2 版。

标签: ios swift


【解决方案1】:

如果您在扩展中向类添加函数(即它们不在类定义中),那么这些方法会在 swift 中静态分派,因为编译器无法将方法添加到类的 vtable(即需要制作 vtable在编译时,但您可以稍后添加扩展,例如在另一个模块中)。这就是为什么编译器抱怨你不能 override 方法(即它们是非虚拟的)。

Objective C dispatch 的工作方式不同,通过选择器表,它甚至可以在运行时进行修改。这就是为什么编译器说使用@objc 并且如果你这样做它肯定会起作用。

示例:

这不会编译,因为我们试图在 swift 中覆盖并动态调度静态调度的非虚函数

extension UITableViewCell {
    func a() {
        print("UITableViewCell")
    }
}

class B: UITableViewCell {
    override func a() {
        print("B")
    }
}

let b = B()
print(b.a())

这行得通,它会打印“B”,因为它使用了 objc 选择器调度

import UIKit
import PlaygroundSupport

extension UITableViewCell {
    @objc func a() {
        print("UITableViewCell")
    }
}

class B: UITableViewCell {
    override func a() {
        print("B")
    }
}

let b = B()
print(b.a())

【讨论】:

  • 德克萨斯州。但是添加更多信息:如果您的覆盖超类在其主声明中取消了 func,但子类在您得到的扩展中这样做:Cannot override a non-dynamic class declaration from an extension。见stackoverflow.com/q/43087698/826946
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-14
  • 2022-01-19
  • 2013-06-03
  • 2017-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多