如果你看看这个功能:
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!
答案 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 []
}