在Swift中投射“as?Int”会为不同的数字生成不同的结果

时间:2015-05-14 10:05:19

标签: ios swift casting null

我有一个工作正常的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;
...

3 个答案:

答案 0 :(得分:2)

您的jsonObject["times_completed"]似乎是一个字符串,而不是一个数字。

因为.integerValue适用于您,因为它是NSString属性。

String投射到Int会崩溃。

你也可以这样做:

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

答案 1 :(得分:1)

我认为jsonObject["times_completed"]返回一个String值,并且像let tcInt = tc as? Int中的Int那样处理String会导致问题。 注意

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

println(a)
println(b)

在两种情况下都打印可选(10)。尝试将其强制转换为String并检查结果let tcInt = tc as? String。如果这是正确的,请不要担心,您的应用程序不会因为您的错误而崩溃,并且可能会在后端更改某些内容

答案 2 :(得分:0)

nil的结果可能是因为jsonObject["times_completed"]无法转换为Int。 尝试将其强制转换为String或其他类型。

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