不支持从扩展名覆盖非@objc声明 [英] Overriding non-@objc declarations from extensions is not supported
问题描述
我似乎无处不在,开始遇到与我经常使用的两个扩展功能相关的数百个错误.
Seemingly out of nowhere I started getting hundreds of errors associated with two extension functions that I use frequently.
我尝试注释掉出现此错误之前的所有新代码.我还尝试清洁构建文件夹.我如何才能克服这篇文章标题中发现的错误?当我成功使用这些扩展包几个月后,为什么它会随机出现?
I tried commenting out all the new code that preceding this error showing up. I also tried cleaning my build folder. How do I get ride of the error found in the title of this post? Why did it randomly appear when I've been using these extensions successfully for months?
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
}
}
推荐答案
如果将函数添加到扩展中的类中(即它们不在类定义中),则这些方法会迅速静态分派,因为编译器无法添加类的vtable的方法(即,需要在编译时创建vtable,但是您可以稍后添加扩展,例如在另一个模块中).这就是为什么编译器抱怨您不能override
方法(即它们是非虚拟的)的原因.
If you add functions to a class in an extension (ie they are not in the class definition) then those methods are statically dispatched in swift because the compiler cannot add the methods to the class's vtable (ie the vtable needs to be made at compile time, but you can add an extension later, such as in another module). This is why the compiler is complaining that you cannot override
the methods (ie they are non virtual).
目标C调度通过选择器表的工作方式有所不同,甚至可以在运行时对其进行修改.这就是为什么编译器说使用@objc
并足够确定是否可以使用它的原因.
Objective C dispatch works differently, via the selector table and it can be modified even at run time. Thats why the compiler says use @objc
and sure enough if you do this it will work.
示例:
无法编译,因为我们试图覆盖并动态地快速分配静态分配的非虚函数
This does not compile because we are trying to override and dynamically dispatch a statically dispatched non virtual function in swift
extension UITableViewCell {
func a() {
print("UITableViewCell")
}
}
class B: UITableViewCell {
override func a() {
print("B")
}
}
let b = B()
print(b.a())
这有效并且打印出"B",因为它使用objc选择器分派
This works and it prints "B" because its using objc selector dispatch
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())
这篇关于不支持从扩展名覆盖非@objc声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!