【问题标题】:Crash in SwiftyJSON during string comparison: swift_unknownRetain字符串比较期间 SwiftyJSON 崩溃:swift_unknownRetain
【发布时间】:2015-03-01 05:01:43
【问题描述】:

我正在从服务器打开一个标志以确定要实例化的对象类型。每种类型都是返回类型的子类(在示例中为Snack。)我的猜测是整个子类与主要问题无关,但为了完整起见,我将其包括在内。

问题是我经常收到 Crashlytics 在 case "chips": 行上报告的崩溃。为了简化初始化程序中的解析,我将服务器响应包装在 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
    }
}

知道为什么这会失败,以及在我们的下一个版本中我可以做些什么来纠正它吗?

【问题讨论】:

    标签: swift crash crashlytics swifty-json


    【解决方案1】:

    发现了问题,男孩是不是很晦涩!

    TL;DR - 通过替换完全避免 SwiftyJSON 的 == 函数

    switch json["SnackName"]
    

    switch json["SnackName"].stringValue
    

    总的来说,这可能是一个好主意,但它之所以必要的原因似乎是 Swift + Foundation 处理字符串的方式中存在的一个 bug。我已经提交了一个开放式雷达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
    

    同样,在调试模式下,此不会崩溃。在 NSString 中将 "foo" 和 "bar" 装箱,或者将 j["foo"] 更改为 j["foo"].stringValue 也可以防止崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      • 2012-12-20
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      相关资源
      最近更新 更多