Swift 无法将 NSNumber 桥接到 Int

Posted

技术标签:

【中文标题】Swift 无法将 NSNumber 桥接到 Int【英文标题】:Swift Unable to bridge NSNumber to Int 【发布时间】:2018-05-09 16:59:09 【问题描述】:

我在UIViewController 里面有UITableView

var userHistory: [[String: Any]] = [[String: Any]]()

override func viewDidLoad() 

    Alamofire.request("http://...").responseJSON  (response) in
        if let responseValue = response.result.value as! [String: Any]? 
            if let responseFoods = responseValue["orders"] as! [[String: Any]]? 
                self.userHistory = responseFoods
                self.collectionView?.reloadData()
            
        

    

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "basCell", for: indexPath) as! BasCollectionViewCell

    let history = userHistory[indexPath.row]
    cell.numberLbl?.text = String(history["id"] as! Int)
    cell.statusLbl?.text = (history["status"] as? String) ?? ""
    let cost = String(history["price"] as! Int) 
    cell.sumLbl?.text = String(cost.dropLast(2)
    cell.dateLbl?.text = (history["date"] as? String) ?? ""

    return cell

问题是当我在模拟器、iPad mini、iPad Pro、iPhone 7 上测试时 - 一切都很好,没有错误

但是当我在 iPhone 5 上启动时给我错误:

致命错误:无法将 NSNumber 桥接到 Int:文件 /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-902.0.48/src/swift/stdlib/public/SDK/Foundation/NSNumber .swift,第 367 行

还有

线程 1:致命错误:无法将 NSNumber 桥接到 Int

对面let cost = String(history["price"] as! Int)

我不明白这是什么类型的问题

【问题讨论】:

什么是userHistory?使用自定义结构或类而不是字典,然后你会神奇地摆脱这个问题。 @vadian ,我更新代码问题 【参考方案1】:

您没有在问题中包含数字的值,因此我无法确认 100%。但是,由于您说它在较新的设备上运行良好但在 iPhone 5 上失败,我认为您正在处理 32 位与 64 位的问题。

如果你用谷歌搜索,你会发现以下内容:

从 2013 年的 iPhone 5S 和 iPad Air 开始,Apple 的所有 iPhone、iPad 和 iPod 此后都包含 64 位芯片。

根据 Swift 文档:link

Int 在大多数情况下,您不需要选择特定大小的整数 在您的代码中使用。 Swift 提供了一个额外的整数类型 Int, 与当前平台的原生字大小相同:

在 32 位平台上,Int 与 Int32 大小相同。

在 64 位平台上,Int 与 Int64 大小相同。

除非您需要使用特定大小的整数,否则请始终使用 Int 表示代码中的整数值。这有助于代码一致性和 互操作性。即使在 32 位平台上,Int 也可以存储任何值 介于 -2,147,483,648 和 2,147,483,647 之间,对于许多人来说足够大 整数范围。

您的值是否超出 32 位 Int 范围?

【讨论】:

好的,但我如何识别这个? 好吧,Swift Int64 变量在 32 位平台上运行良好,因此您可以直接转换为该变量。但是,您始终可以在尝试转换为 Int 之前注销代码中的值(以确定它是否超过 2.1B 数字)。【参考方案2】:

Swift 4 使 NSNumber 桥接更加严格。如果 NSNumber 不能由 Int 表示,则转换在运行时失败。 您可以改为将其类型转换为 Double,但由于您提到这仅在 iPhone 5 上失败,我们将安全地为这两种情况进行类型转换。

替换:

let cost = String(history["price"] as! Int) 

与:

var cost = ""
if let price = dict["price"] as? Int 
    cost = "\(price)"

else if let price = dict["price"] as? Double 
    cost = "\(price)"

【讨论】:

更容易转换为 Int64。 @gasher729 但是如果 OP 的号码适合 Int,这可能会失败。即这样的事情会失败:let dict: [String:Any] = ["price":1050]let cost = dict["price"] as! Int64

以上是关于Swift 无法将 NSNumber 桥接到 Int的主要内容,如果未能解决你的问题,请参考以下文章

是否可以为 (U)Int8/16/32/64 类型复制 Swifts 自动数值桥接到 Foundation (NSNumber)?

将 Obj-C 桥接到 Swift 后缺少啥

Swift 4.2 升级后将 Swift 类桥接到 React Native

在 Swift 3 中使用 NSNumber 和整数值

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

无法使用桥接头将 Objective-C 文件导入 Swift 项目