处理Swift Dicts:致命错误:不能在不同大小的类型之间使用unsafeBitCast

时间:2015-12-29 20:46:47

标签: swift casting fatal-error

我在Swift中有一个需要能够处理多种类型的函数。具体来说,它需要能够解析Dicts和Strings。

我遇到的问题是Dicts可能有几种类型,具体取决于它们的来源。因此,我可以获得[String:Any][String:String](来自Swift)或[String:AnyObject](来自objc)。顶级解析函数使用Any,然后测试特定类型并尝试解析它们。

首先我尝试测试if let dict = object as? [String:Any],但如果我传入其他类型[String:AnyObject][String:String]则失败。所以我尝试测试每种类型:

func parseLink(object: Any) {

    if let dict = object as? [String:Any] {
      return self.parseDict(dict)
    } else if let dict = object as? [String:AnyObject] {
      return self.parseDict(dict)
    } else if let dict = object as? [String:String] {
      return self.parseDict(dict)
    } else if let string = object as? String {
      return parseURL(string)
    }
}

func parseDict(dict: [String:Any]) { ..... }

所以我创建了一些单元测试来测试行为:

  func testDictTypes() {
    let testDict: [String:Any] = [ "orgId" : "123456789" ]

    let link = OrgContextLinkParser().parseLink(testDict)
    XCTAssertNotNil(link)

    let testDict1: [String:AnyObject] = [ "orgId" : "123456789" ]

    let link2 = OrgContextLinkParser().parseLink(testDict1)
    XCTAssertNotNil(link2)

    let testDict3: [String:String] = [ "orgId" : "123456789" ]

    let link3 = OrgContextLinkParser().parseLink(testDict3)
    XCTAssertNotNil(link3)
  }

这一切都编译得很好,但如果传入[String:AnyObject],我会遇到致命的运行时错误。这很麻烦,因为Swift的类型系统应该可以防止这类错误,并且我没有得到任何警告或错误我编译。

我也真的不想多次复制完全相同的逻辑来处理不同的dict类型。 I.E.,处理[String:Any][String:AnyObject][String:String]实际上具有完全相同的逻辑。

我见过的唯一可能的解决方案是实际复制字典,这看起来相当昂贵(Convert [String: AnyObject] to [String: Any])。出于性能原因,最好只复制粘贴代码并更改功能签名......但实际上!这似乎太过分了。

最佳解决方案似乎是将Dict解析为[String:AnyObject]并复制值如果它是[String:Any]

if let dict = object as? [String:Any] {
  var objDict: [String:AnyObject] = [:]
  for (key, value) in dict {
    if let obj = value as? AnyObject {
      objDict[key] = obj
    }
  }
  return self.parseDict(objDict)

我不是特别喜欢这个,但到目前为止,我能够想出最好的。

有没有人知道如何正确处理这个问题?我特别担心我可以将Any转换为[String:AnyObject],将其传递给一个带[String:Any]的函数,并且我没有编译错误,即使它在运行时崩溃。

0 个答案:

没有答案