Swift 中的 UnsafeMutablePointer<CFTypeRef> 3

UnsafeMutablePointer<CFTypeRef> in Swift 3

我试图在我的钥匙串实用程序 class 中调用 SecItemCopyMatching 以便从钥匙串中获取数据,但我 运行 遇到了获取result 参数,UnsafeMutablePointer<CFTypeRef?>.

原始语句(在 Swift 2 中,在迁移到 Swift 3 之前)是

// query is a dictionary of [String : AnyObject]

var result: Data?
let status = withUnsafeMutablePointer(to: &result) {
    SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer([=12=]))
}

但在Swift 3 中,您现在需要调用.withMemoryRebound 才能查看内存。根据 Xcode 的指示,我尝试了这个

var result: Data?
let status = withUnsafeMutablePointer(to: &result){
    [=13=].withMemoryRebound(to: Data.self, capacity: 1){
        SecItemCopyMatching(query as CFDictionary, UnsafePointer([=13=]))
    }
}

然而这样做,我得到一个错误

Cannot convert value of type 'UnsafePointer<_>' to expected argument type 'UnsafeMutablePointer<CFTypeRef?>?'

所以,我尝试使用 CFTypeRef 而不是 Data

var result: CFTypeRef?
let status = withUnsafeMutablePointer(to: &result){
    [=14=].withMemoryRebound(to: CFTypeRef.self, capacity: 1){
        SecItemCopyMatching(query as CFDictionary, UnsafePointer([=14=]))
    }
}

UnsafePointer([=23=]) 替换为简单的 [=24=] 会导致相同的错误消息。

如何获得用于从钥匙串获取数据的 UnsafeMutablePointer<CFTypeRef?>

错误消息有点误导 - 实际问题是 result 必须是 AnyObject? - withMemoryRebound 不需要使用。

var result: AnyObject?
let status = withUnsafeMutablePointer(to: &result){
    SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer([=10=]))
}

按预期工作并从钥匙串获得正确结果 - 只需将其转换为 Data。事实上,.

所以,我的新密码是

var query: [String : AnyObject] = [:]
//set up the query

var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)

var data: Data?
if status == noErr{
    data = result as? Data
}

在您的情况下,您不需要使用 withMemoryReboundwithUnsafeMutablePointer(to:)

相反,您可以使用

var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)

if status == noErr, let data = result as? Data {
    //use data...
}

通常,当您需要将 UnsafeMutablePointer<T> 传递给函数时,声明一个 T 类型的变量并将其作为输入参数 &variable 传递。在您的情况下,TCFTypeRef?,而在 Swift 3 中,CFTypeRef 只是 AnyObject.

的类型别名

即使在 Swift 2.2 中,您也不需要使用 withUnsafeMutablePointer

var result: AnyObject?  
let status = SecItemCopyMatching(query, &result)