字符串比较期间 SwiftyJSON 崩溃:swift_unknownRetain
Crash in SwiftyJSON during string comparison: swift_unknownRetain
我正在从服务器打开一个标志以确定要实例化的对象类型。每种类型都是 return 类型(示例中的 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 at 0x0000000093a4bec8" 和 "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
}
}
知道为什么会失败吗?我可以在下一个版本中纠正它吗?
找到问题了,小伙子是不是很晦涩!
TL;DR - 通过替换
完全避免 SwiftyJSON 的 ==
函数
switch json["SnackName"]
和
switch json["SnackName"].stringValue
总的来说,这可能是个好主意,但它之所以有必要,似乎是 Swift + Foundation 处理字符串的方式中的一个错误。我已提交公开雷达 here。
重现这个问题只需要Xcode6.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
同样,在调试模式下,不会 崩溃。在 NSString 中装箱 "foo" 和 "bar",或将 j["foo"]
更改为 j["foo"].stringValue
也可以防止崩溃。
我正在从服务器打开一个标志以确定要实例化的对象类型。每种类型都是 return 类型(示例中的 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 at 0x0000000093a4bec8" 和 "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
}
}
知道为什么会失败吗?我可以在下一个版本中纠正它吗?
找到问题了,小伙子是不是很晦涩!
TL;DR - 通过替换
完全避免 SwiftyJSON 的==
函数
switch json["SnackName"]
和
switch json["SnackName"].stringValue
总的来说,这可能是个好主意,但它之所以有必要,似乎是 Swift + Foundation 处理字符串的方式中的一个错误。我已提交公开雷达 here。
重现这个问题只需要Xcode6.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
同样,在调试模式下,不会 崩溃。在 NSString 中装箱 "foo" 和 "bar",或将 j["foo"]
更改为 j["foo"].stringValue
也可以防止崩溃。