iPhone从钥匙串(keychain)中获取数据字典

标签 iphone dictionary keychain automatic-ref-counting

所以我正在尝试将旧项目转换为自动引用计数。我正在尝试使用 xCode 具有的转换工具,但它说要在转换之前修复一些问题。我不知道如何修复这个错误。它在钥匙串(keychain)文件的实现中。此方法会返回错误,特别是带有 SecItemCopyMatching 的行。我收到的错误是:“ARC 不允许将间接指针转换为 Objective-C 指针到‘CFTypeRef*’(又名‘const void**’)。我一直在查看 google、apple 文档,和一堆其他废话,无法找到更好的方法来获取钥匙串(keychain)中的现有数据字典。感谢任何帮助。谢谢!

-(NSMutableDictionary*)fetchDictionary {

NSMutableDictionary *genericPasswordQuery = [self buildSearchQuery];

NSMutableDictionary *outDictionary = nil;
OSStatus status = SecItemCopyMatching((__bridge_retained  CFDictionaryRef)genericPasswordQuery, (CFTypeRef*)&outDictionary);

if (DEBUG) printf("FETCH: %s\n", [[self fetchStatus:status] UTF8String]);

if (status == errSecItemNotFound) return NULL;
return outDictionary;

}

最佳答案

您不需要为此禁用 ARC;您只需将查询结果声明为 CFDictionaryRef,然后在调用后将其转换为 NSDictionary

/*1*/ CFDictionaryRef cfquery = (__bridge_retained CFDictionaryRef)genericPasswordQuery;
/*2*/ CFDictionaryRef cfresult = NULL;
/*3*/ OSStatus status = SecItemCopyMatching(cfquery, (CFTypeRef *)&cfresult);
/*4*/ CFRelease(cfquery);
/*5*/ NSDictionary *result = (__bridge_transfer NSDictionary *)cfresult;

几点说明:

  • 在第 1 行中,我们将查询从 cocoa 土地转换为核心基金会国家/地区。我们使用 __bridge_retained 来确保 ARC 在我们使用对象时不会释放和取消分配该对象。这种桥接强制转换会保留对象,因此为了防止泄漏,必须在其后的某处添加相应的CFRelease。 SecItemCopyMatching 肯定不会为我们释放查询,所以如果我们使用保留桥,那么我们需要自己释放生成的 Core Foundation 对象。 (我们在第 4 行中执行此操作。)
  • 第 2、3 和 4 行是使用 Core Foundation 类型的纯 C 代码,因此 ARC 不会对它们执行任何操作或提示。
  • 在第 5 行中,我们告诉 ARC,SecItemCopyMatching 已创建保留计数为 1 的结果,我们负责释放该结果。 (我们知道这一点是因为它的名称中包含“Copy”。)__bridge_transfer 让 ARC 了解此职责,因此它将能够自动为我们完成此操作。
  • 不要将 SecItemCopyMatching 返回的不可变 Core Foundation 字典转换为 NSMutableDictionary;那是错误的。此外,buildSearchQuery 返回一个 NSMutableDictionary 也违反了一般的 Cocoa 风格约定。简单的 NSDictionary 在这两种情况下都可以正常工作。

这里的经验法则是 __bridge_retained 后面需要跟一个 CFRelease,而“Copy”或“Create”函数的结果必须转换为Cocoa-land 使用 __bridge_transfer

关于iPhone从钥匙串(keychain)中获取数据字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7827730/

相关文章:

iphone - 无法将应用程序上传到 iTunes Connect

iphone - ES 2.0 多 channel 和渲染到纹理的实现

c# - 什么会导致 dictionary.ContainsKey(dictionary.Keys.First()) 返回 false?

python - 在 2D Python 数字字典中插入值

python - 如何根据键值和嵌套值编辑嵌套字典中的值

IOS 钥匙串(keychain)服务

iphone - 使 MKMapView 透明但保持覆盖层不透明

macos - 如何在Mail.app中运行的applescript中使用钥匙串(keychain)中的密码?

ios - 钥匙串(keychain)中的密码 - 人们忘记了密码

iphone - 有没有人有核心数据中获取属性的工作示例?