在 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...
}
我有一个 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...
}