Swift 1.2将[AnyObject?]转换为[AnyObject]

时间:2015-07-29 20:47:30

标签: swift compiler-errors

如果你看看这个功能:

typealias JSONDictionary = [String: AnyObject]

private func allIdentifiersInJson(json: [JSONDictionary], key: String?) -> [AnyObject] {
        if let identifier = key {
            let identifiers = json.map{ $0[identifier] } //this returns [AnyObject?]
            return identifiers as? [AnyObject] ?? [] // this crashes the compiler in Release with Optimizations
        }
        return []
    }

如何将[AnyObject?]转换为[AnyObject]

在启用了优化的Release配置中,我在编译期间收到此错误:

Bitcast requires both operands to be pointer or neither
  %548 = bitcast i64 %547 to %objc_object*, !dbg !10033
LLVM ERROR: Broken function found, compilation aborted!

4 个答案:

答案 0 :(得分:3)

一种方法是使用flatMap:

let l: [AnyObject?] = [1, 2, 3, 4, 5, 6, nil, 7]
let m = l.flatMap { $0 } // Returns [1, 2, 3, 4, 5, 6, 7] as [AnyObject]

(仅在Swift 2中测试)

答案 1 :(得分:1)

你可能想要使用这样的东西:

private func allIdentifiersInJson(json: [JSONDictionary], key: String?) -> [AnyObject] {
    if let key = key {
        return json.map { $0[key] }.filter { $0 != nil } as! [AnyObject]
    }
    return []
}

由于我们正在使用filter删除nil的所有实例,因此我们可以使用强制转换为[AnyObject],而不必担心崩溃。

或者,正如@MirekE在回答中指出的那样,flatMap更加简洁:

return json.flatMap { $0[key] }

仅返回非零结果,并且无需任何转换。

答案 2 :(得分:1)

扩展上述评论中的内容,如果您使用以下内容,如果identifier不是字典中的关键字,您的应用就会崩溃:

let identifiers = json.map { $0[ identifier ]! }

所以,您可能想要做的是首先过滤,然后执行映射,因为您已经检查过该密钥,因此您可以强制解包:

let identifiers = json.filter({ $0[ identifier ] != nil }).map { $0[ identifier ]! }

但是,如果是我,我想彻底摆脱整体安全的力量,甚至当其他人甚至是你自己一周后回到这个代码时,也可以通过取出过滤器:

let identifiers = json.map({ $0[ identifier ] ?? NSNull() }).filter { !($0 is NSNull) }

现在您可以安全地使用nil合并运算符(??)展开并提供默认对象(NSNull),然后过滤掉这些默认对象。

答案 3 :(得分:0)

此函数不会使编译器崩溃:

private func allIdentifiersInJson(json: [JSONDictionary], key: String?) -> [AnyObject] {
    if let key = key {
        let identifiers = json.map{ $0[key]! } //this returns [AnyObject]
        return identifiers ?? []
    }
    return []
}