向下转换时出现 Swift 错误 'Any'

标签 swift downcast optional-values

以下代码几乎与Apple Documentation 完全相同并编译无误:

guard let firstItem = (rawItems! as? Array<Dictionary<String, Any>>)?.first else {
    throw AnError()
}

let identityRef = firstItem[kSecImportItemIdentity as String] 
               as! SecIdentity?   // !!!

guard let identity = identityRef else {
    throw AnError()
}

标有!!! 的行包含强制向下转换,将as! 替换为as 很明显会导致编译错误“有吗?”不能转换为“SecIdentity?”... 事实上 SecIdentity 是一个类,而 Any 甚至可能不是一个类。

我真正无法解释的是以下内容。如果我试图通过使用这个来使代码更安全

guard let idenity = firstItem[kSecImportItemIdentity as String] as? SecIdentity
else {
    throw AnError()
}

或者这个

guard let idenityRef = firstItem[kSecImportItemIdentity as String] as? SecIdentity?
else {
    throw AnError()
}

我收到编译错误:条件向下转换为 CoreFoundation 类型“SecIdentity”将始终成功

最佳答案

SecIdentity“表示身份的抽象 Core Foundation 类型对象”, Core Foundation 类型的类型可以是 使用 CFGetTypeID() 检查。所以你可以先检查类型ID。如果它匹配一个 SecIdentity 那么强制转换是安全的:

guard let cfIdentity = firstItem[kSecImportItemIdentity as String] as CFTypeRef?,
    CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
        throw AnError()
}
let identity = cfIdentity as! SecIdentity

另请参阅错误报告 SR-7015 The CoreFoundation conditional downcast diagnostic is not as helpful as it should be :

The diagnostic should be updated with a message that informs the developer to compare CFTypeIds (with a fixit if possible).

关于向下转换时出现 Swift 错误 'Any',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51805574/

相关文章:

swift: if-let 并行赋值

swift - 有没有办法在本地 iOS Web 服务器中使用 Vapor 加载 HTML/JS 文件?

ios - 收到错误 "Cannot connect to pasteboard server"。 swift

notifications - Swift 和 NSUserNotification - 没有横幅或警报,但会静默添加到通知列表中

c++ - 如何避免垂头丧气?

Java传递变量——向下转型

swift - 为什么 ImageView 有时不会出现在 Collection View 单元格中?

C++ 避免向下转型

swift - 为什么这样做有效(不使用与使用可选值)?

swift - 是否需要将变量 'possibleIntegerValue' 设置为 'optional Int(Int?)',或者将 'possibleIntegerValue' 设置为类型 'Int' 是否可以?