我从服务器切换标志以确定要实例化的对象类型。在示例中,每个类型都是返回类型(Snack
的子类。)我的猜测是整个子类事物与主要问题无关,但我将其包含在内以保证完整性。
麻烦的是,我一直在case "chips":
线上的Crashlytics报告崩溃事件。为了简化初始化程序中的解析,我将服务器响应包装在SwiftyJSON JSON
中。这一切都在测试中运行良好。
class func fromJSON(json: JSON) -> Snack {
switch json["SnackName"] {
case "chips": // CRASH OCCURS HERE
return BagOChips(json: json)
case "apple":
return Apple(json: json)
default:
return Spam(json: json)
}
}
具体来说,崩溃发生在" SwiftyJSON.swift:1013" (标在下面)。 Crashlytics将其描述为" EXC_BAD_ACCESS KERN_INVALID_ADDRESS位于0x0000000093a4贝塞和#34;和" swift_unknownRetain + 32"。
public func ==(lhs: JSON, rhs: JSON) -> Bool {
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return (lhs.object as NSNumber) == (rhs.object as NSNumber)
case (.String, .String):
return (lhs.object as String) == (rhs.object as String) // CRASH REALLY OCCURS HERE
case (.Bool, .Bool):
return (lhs.object as Bool) == (rhs.object as Bool)
case (.Array, .Array):
return (lhs.object as NSArray) == (rhs.object as NSArray)
case (.Dictionary, .Dictionary):
return (lhs.object as NSDictionary) == (rhs.object as NSDictionary)
case (.Null, .Null):
return true
default:
return false
}
}
知道为什么会失败以及我可以在下一个版本中做些什么来纠正它?
答案 0 :(得分:5)
发现了问题,而男孩却模糊不清!
TL; DR - 通过替换
完全避免使用SwiftyJSON的==
功能
switch json["SnackName"]
与
switch json["SnackName"].stringValue
总的来说,这可能是一个好主意,但它的必要原因似乎是Swift + Foundation如何处理字符串的一个漏洞。我已经提交了一个开放的雷达here。
重现此问题所需要的只是Xcode 6.1,SwiftyJSON以及我提交给Apple的以下示例代码:
let d = NSDictionary(dictionary: ["foo": "bar"])
let j = JSON(d)
switch (j["foo"]) {
case "bar":
println("> No crash!")
default:
println("> default")
}
然后在您的SwiftyJSON副本中输入这些日志记录语句。
public func ==(lhs: JSON, rhs: JSON) -> Bool {
// Next 2 lines added just for SwiftyCrasher test project.
println( "> Left: \(_stdlib_getTypeName(lhs.object))" )
println( "> Right: \(_stdlib_getTypeName(rhs.object))" )
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return (lhs.object as NSNumber) == (rhs.object as NSNumber)
case (.String, .String):
...
}
这显示了崩溃前的以下控制台输出:
> Left: _TtCSs19_NSContiguousString
> Right: _TtCSs19_NSContiguousString
同样,在调试模式下,此不会崩溃。拳击" foo"和" bar"在NSString中,或将j["foo"]
更改为j["foo"].stringValue
也可以防止崩溃。