【问题标题】:UnsafeMutablePointer<CFTypeRef> in Swift 3Swift 3 中的 UnsafeMutablePointer<CFTypeRef>
【发布时间】:2017-01-19 09:27:47
【问题描述】:

我试图在我的钥匙串实用程序类中调用 SecItemCopyMatching 以便从钥匙串中获取数据,但在获取 result 参数 UnsafeMutablePointer&lt;CFTypeRef?&gt; 时遇到了问题。

最初的声明(在 Swift 2 中,在迁移到 Swift 3 之前)是

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

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

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

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

但是这样做,我得到一个错误

无法将“UnsafePointer&lt;_&gt;”类型的值转换为预期的参数类型“UnsafeMutablePointer&lt;CFTypeRef?&gt;?

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

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

UnsafePointer($0) 替换为简单的$0 会导致相同的错误消息。

如何获得UnsafeMutablePointer&lt;CFTypeRef?&gt; 用于从钥匙串中获取数据?

【问题讨论】:

  • 请您发布您创建查询的方式。我以前只是这样做并从 swift Dictionary 转换为 CFDictionary,但这在 Swift 3 中不再适用于我。如果我能看到更多的代码,我可以应用这个解决方案。
  • @TimSpears 您的代码的问题可能是字典必须是[String : AnyObject] - 自动迁移器(对我而言)将其更改为[String : Any]。我更新了my answer to the question 以包含我使用的代码

标签: swift swift3 core-foundation unsafe-pointers unsafemutablepointer


【解决方案1】:

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

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

按预期工作并从钥匙串中获得正确的结果 - 只需将其转换为 Data。其实withUnsafeMutablePointer doesn't even have to be used

所以,我的新代码是

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
}

【讨论】:

  • 我尝试了您的解决方案和@OOPer 的解决方案,但似乎都不适合我,请在此处查看我的评论。知道发生了什么吗?
【解决方案2】:

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

相反,您可以使用

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

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

通常,当您需要将UnsafeMutablePointer&lt;T&gt; 传递给函数时,请声明T 类型的变量并将其作为inout 参数&amp;variable 传递。在您的情况下,TCFTypeRef?,而在 Swift 3 中,CFTypeRef 只是 AnyObject 的类型别名。


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

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

【讨论】:

  • 您的解决方案对我有用。我的结果变量(使用 var 定义,而不是 let)是一个 SecKey,它很容易转换为 CFTypeRef。仅使用 & 符号会导致错误 Cannot pass immutable value of type 'CFTypeRef?' as inout argument
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多