【问题标题】:Unable to bridge NSNumber to Float Swift 3.3无法将 NSNumber 桥接到 Float Swift 3.3
【发布时间】:2018-04-04 02:38:55
【问题描述】:

在 Xcode 更新后,我遇到了一个奇怪的问题。在我的应用程序中,当我从 API 获得响应时,我会手动解析它并将其映射到我的模型。在我的代码中有很多地方,我将 JSON 值转换为 Float,并使用如下所示的 null 合并:

randomVariable = jsonDict["jsonKey"] as? Float ?? 0

以前可以正常工作,但更新后总是默认为 0。为了确定原因,我尝试将其强制转换为 Float,如下所示

randomVariable = jsonDict["jsonKey"] as! Float

这导致了以下错误

无法将 NSNumber 桥接到 Float

经过进一步调查,我发现 Xcode 使用的是 Swift 3.3(之前使用的是 Swift 3.2)。我在 StackOverflow 上找到的解决方案围绕着将其转换为 NSNumber 而不是 Float。正如我上面提到的,我的应用程序中分布着类似的代码行。我想知道是否有办法解决这个问题。也许使用某种扩展?

【问题讨论】:

  • 使用 Xcode 9.2 和 Swift 4.0 转换为 Float 效果很好。
  • 是的。这是 Xcode 9.3 和 Swift 3.3 的问题。
  • Xcode 9.3 使用 Swift 4.1。
  • 我知道这一点。它还支持 swift 3.3。由于我的代码库在 swift 3 中,因此它默认为 swift 3.3。

标签: json swift


【解决方案1】:

如您所见,您可能需要先将其转换为 NSNumber

类似这样的:

randomVariable = (jsonDict["jsonKey"] as? NSNumber)?.floatValue ?? 0

也许正则表达式替换会帮助您更新代码。

模式:jsonDict\[([^\]]*)\] as\? Float

替换为:(jsonDict[$1] as? NSNumber)?.floatValue

【讨论】:

  • 感谢您的推荐。我会接受这个答案,因为它确实提供了解决方案。虽然在我的情况下,它会导致大规模测试,所以我最终将我的 Xcode 恢复到 9.2
  • 赞成,在我的情况下,我没有很多浮点映射,因此逐个文件更新而不是项目明智
【解决方案2】:

问题出在 32 位 架构中,并在 swift 4.1 中更新了 NSNumber 类。

例如,当我将数字 1.1 写入字典时,它将存储为 64 位 NSNumber,最准确的表示 = 1.10000000000000008881784197001...

所以,当你把这个数字读成!浮动它会失败,因为 32 位精度不足以获得最准确的表示。

32 位最准确的表示 = 1.10000002384185791015625

64 bit presentation of float number

因此,您需要获取在 NSNumber.floatValue() 函数中实现的截断结果。

randomVariable = (jsonDict["jsonKey"] as! NSNumber).floatValue

【讨论】:

  • 这绝对是我看到的问题。针对具有不同有效数字和不同 Swift 版本的多个 NSNumber 进行了测试。
【解决方案3】:

在我发现SwiftyJSON 之前,我曾经这样做过,手动解析数据。您可能想深入了解他们的源代码,看看它是如何解析您的数据的。

// Sample: rate is a Float

// Number
if let number = dictionary[SerializationKeys.rate] as? NSNumber {
    print("IS A NUMBER")
    rate = number.floatValue
}

// String

if let string = dictionary[SerializationKeys.rate] as? String {
    print("IS A STRING")
    let decimalNumber = NSDecimalNumber(string: string)
    rate = decimalNumber.floatValue
}

既然我提到了SwiftyJSON,我想推荐它以避免这样的头痛。把json的解析交给那个人。 https://github.com/SwiftyJSON/SwiftyJSON

希望对你有帮助。

【讨论】:

  • 我现在知道SwiftyJSON,但是当我开始构建这个应用程序时我还没有。更好的方法是将它更新到 Swift 4,因为它有自己的解析器。但无论哪种情况,问题都是代码库很大,更新所有代码库需要很长时间。这就是为什么我一直在寻找这个问题背后的一些见解,以便提出快速解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多