无法将 NSNumber 类型的值转换为预期的参数类型 NSNumber

Cannot convert value of type NSNumber to expected argument type NSNumber

我在尝试使用从基 class

继承的泛型函数的参数时遇到标题错误

基础class:

BaseBottomBar: UIView {
    ...
    func formatDetailText<T>(value: T...) {
        assertionFailure("You shouldn't be using this base class")
    }
}

Child class:

NewTicketBottomBar: BaseBottomBar {

    override func formatDetailText<NSNumber>(value: NSNumber...) {
        let priceAsCurrencyString = NumberFormatter.currencyFormatter.string(from: value[1]) //Error on this line
        assert(priceAsCurrencyString != nil, "The price cannot be nil")
        let newTicketText = String(format: "%4.0f", value[0]) + " / TOTAL : " + priceAsCurrencyString!
        detailLabel.text = newTicketText
    }
}

我想我的基本方法原型在某种程度上是错误的,但我看不出是怎么回事。

一开始我没有使用通用方法,原型如下:

func formatDetailText(value: Double...) {
    ...
    let priceAsCurrencyString = NumberFormatter.currencyFormatter.string(from: NSNumber(value: value[1]))
    ...
}

这工作正常

如有任何帮助,我们将不胜感激

你似乎认为

override func formatDetailText<NSNumber>(value: NSNumber...) {

将覆盖方法中的泛型 <T> 解析为 NSNumber。它没有。它只是为通用引入了一个不同的名称;这里的 NSNumber 不是 NSNumber class,它只是另一个通用的占位符名称,与 T 完全一样(实际上,它 T 的另一个名称)。

所以很自然地,当您尝试在 NumberFormatter 的 string(from:) 中预期使用 NSNumber 的地方使用此占位符时,编译器转身说,"Dude [the compiler is from California, this is how it talks], I have no reason to think that your placeholder called "NSNumber" 实际上是 NSNumber。"

你需要给它一个这样想的理由。你的意思可能是

override func formatDetailText<T>(value: T...) where T : NSNumber {

问题是您的代码没有说明参数必须是 NSNumber。它是说它需要一个你想调用的通用类型 NSNumber,就像你在上面使用 T 一样。

错误信息是因为不能向编译器保证被称为NSNumber的泛型类型是一个真正的NSNumber实例。你可以将一个字符串传递给它,因为它知道。

您的覆盖应如下所示

override func formatDetailText<T: NSNumber>(value: T...)