不支持从扩展名覆盖非@objc声明 [英] Overriding non-@objc declarations from extensions is not supported

查看:357
本文介绍了不支持从扩展名覆盖非@objc声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无处不在,开始遇到与我经常使用的两个扩展功能相关的数百个错误.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆