在 Swift 中转换 "as? Int" 会对不同的数字产生不同的结果

Casting "as? Int" in Swift yields different results for different numbers

我有一个 iOS 应用程序运行良好,直到某个时候它开始在某个数字的 nil 值上崩溃。

在我的代码中做了一些测试后,我设法将其归结为以下代码,它产生的输出对我来说根本没有意义:

let tc: AnyObject? = jsonObject["times_completed"]
let pos: AnyObject? = jsonObject["position"]

println("TC FROM JSON \(tc)")
println("POS FROM JSON \(pos)")

println("TC TYPE: \(_stdlib_getDemangledTypeName(tc))")
println("POS TYPE: \(_stdlib_getDemangledTypeName(pos))")

let tcInt = tc as? Int
let posInt = pos as? Int

println("TC TYPE: \(_stdlib_getDemangledTypeName(tcInt))")
println("POS TYPE: \(_stdlib_getDemangledTypeName(posInt))")

println("TC: \(tcInt)")
println("POS: \(posInt)")

输出:

TC FROM JSON Optional(648)
POS FROM JSON Optional(6)

TC TYPE: Swift.Optional<Swift.AnyObject>
POS TYPE: Swift.Optional<Swift.AnyObject>

TC TYPE: Swift.Optional<Swift.Int>
POS TYPE: Swift.Optional<Swift.Int>

TC: nil
POS: Optional(6)

如您所见,我们这里有两个 Int,其中一个最终成为 nil (TC),另一个最终保持预期值 (POS)。

由于代码一直有效,我怀疑数字本身可能有问题(太高了?)。

以不同的方式转换 Int 会有所帮助,例如:

let tcInt = tc?.integerValue

但这意味着我必须重新提交我的应用程序,这需要一些时间。我想避免这种情况,也许通过(暂时)更改 times_completed

的值

谁能解释一下这里发生了什么?谢谢。


更新:

请同时检查下面的 JSON 中的一段。好像不是字符串,而是数字。关键 一个字符串,但这有关系吗?

...
position = 6;
slug = "my-quiz";
"times_completed" = 648;
...

我认为 jsonObject["times_completed"] 正在返回一个 String 值,并且在 let tcInt = tc as? Int 中像对待 Int 一样对待 String 会导致问题。 请注意

var a : AnyObject? = 10
var b : AnyObject? = "10"

println(a)
println(b)

在两种情况下都打印 Optional(10)。尝试将其转换为字符串并检查结果 let tcInt = tc as? String。如果那是正确的,请不要担心,您的应用程序不会因为您的错误而崩溃,也许后端中的某些内容已更改

看来你的jsonObject["times_completed"]是一个字符串而不是数字。

并且因为 .integerValue 对你有效证明了这一点,因为它是 NSString 属性。

并且将 String 转换为 Int 会崩溃。

你也可以这样做:

let tcInt = (jsonObject["times_completed"] as? String)?.toInt()

nil的结果可能是因为jsonObject["times_completed"]不能转换为Int。 尝试将其转换为字符串或其他类型。

if let tcStr = jsonObject["times_completed"] as? String {
    // string...
}