【问题标题】:Using Unmanaged<AnyObject>! as key in NSMutableDictionary使用非托管<AnyObject>!作为 NSMutableDictionary 中的键
【发布时间】:2014-06-14 01:20:21
【问题描述】:

我正在尝试创建钥匙串查询,但在将属性项键用作字典键时遇到了困难。创建字典时,我可以将包含在数组中的属性项作为字典键传递,就像这样,没有任何问题

genericPasswordQuery = NSMutableDictionary(objects: [kSecClassGenericPassword, identifier], forKeys: [kSecClass, kSecAttrGeneric])

但是,如果我尝试向查询字典中添加另一个类似的项目,如下所示:

genericPasswordQuery.setObject(accessGroup, key:kSecAttrAccessGroup)

它抱怨密钥不符合 NSCopying 并提供类型错误:

“找不到接受所提供参数的 'setObject' 的重载”

这是 SecItemAdd 的标准实现,但我在 Swift 中遇到问题。

【问题讨论】:

  • kSecAttrAccessGroup 是如何定义的?
  • 是否有必要使用 NSMutableDictionay?您的代码也可以与 Swift 字典一起使用吗?您的优势在于您的密钥不需要符合 NSCopying 标准。
  • @Areal-17 使用 swift 词典,我收到错误“无法从 Dictionary 转换为 DictionaryLiteralConvertible”

标签: swift keychain


【解决方案1】:

我想我找到了解决方案。来自docs

当 Swift 导入未注解的 API 时,编译器 无法自动对返回的 Core Foundation 进行内存管理 对象。 Swift 将这些返回的 Core Foundation 对象包装在一个 非托管结构。全部间接归还核心基金会 对象也是非托管的。

当您收到来自未注释 API 的非托管对象时,您 应该在你之前立即将它转换为内存管理对象 使用它。这样,Swift 可以为您处理内存管理。 非托管结构提供了两种方法来转换 非托管对象到内存托管对象——takeUnretainedValue() 和 取RetainedValue()。

当前实现:

genericPasswordQuery = NSMutableDictionary(objects: [kSecClassGenericPassword, identifier], forKeys: [kSecClass, kSecAttrGeneric])

var kSecAttrAccessGroupSwift: NSString = kSecAttrAccessGroup.takeRetainedValue() as NSString
genericPasswordQuery.setObject(accessGroup, forKey: kSecAttrAccessGroupSwift)

这在 Xcode 中运行良好,但是当我添加 .takeRetainedValue 时,Playground 会立即崩溃

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多