iPhone从钥匙串提取数据字典 [英] iPhone fetch data dictionary from keychain

查看:201
本文介绍了iPhone从钥匙串提取数据字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图将一个旧的项目转换为自动引用计数。我正在尝试使用xCode的转换工具,但它说可以修改几件事情,然后才能转换。我不知道如何解决这个错误。它正在执行钥匙串文件。该方法是返回错误的方法,特别是与SecItemCopyMatching的行。我正在得到的错误说:对于指向CFTypeRef *(即const void **)的Objective-C指针的间接指针的转换不允许使用ARC。我一直在遍及谷歌,苹果文档,和一堆其他的垃圾,找不到更好的方法来获取钥匙串中现有的数据字典。任何帮助,谢谢!

So I'm trying to convert an old project to Automatic Reference Counting. I'm trying to use the conversion tool that xCode has but it says to fix a couple things before it can convert. I have no idea how to fix this error. It's in the implementation of the keychain file. This method is the one that returns the error, specifically the line with the SecItemCopyMatching. The error I am getting says: " Cast of an indirect pointer to an Objective-C pointer to 'CFTypeRef*' (aka 'const void**') is disallowed with ARC. I've been looking all over google, apple docs, and a bunch of other crap and can't find a better way to fetch an existing data dictionary in the keychain. Any help appreciated. Thanks!

-(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

You don't need to disable ARC for this; you just need to declare the query's result as a CFDictionaryRef, then cast it to an NSDictionary after the call.

/*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行中,我们将查询从可可土地转换为Core Foundation国家。我们使用 __ bridge_retained 来确保ARC在我们使用它时不释放和释放对象。这种桥接方式保留对象,因此为了防止泄漏,必须在某处存在相应的 CFRelease SecItemCopyMatching 肯定不会释放我们的查询,所以如果我们使用一个保留的桥,那么我们需要释放所产生的Core Foundation对象。 (我们在第4行做)。

  • 第2,3行和第4行是使用Core Foundation类型的纯C代码,因此ARC将无关或不抱怨。 li>
  • 在第5行中,我们告诉ARC, SecItemCopyMatching 创建了一个保留计数为1的结果,我们负责发布。 (我们知道这是因为它的名字为复制。) __ bridge_transfer 让ARC知道这个责任,所以它可以自动为我们做。 li>
  • 不要将SecItemCopyMatching返回的不可变的Core Foundation字典转换为 NSMutableDictionary ;这只是错误此外,它反对一般的可可风格约定, buildSearchQuery 返回一个 NSMutableDictionary 。在这两种情况下,简单的 NSDictionary s可以正常工作。

  • In line 1, we convert the query from Cocoa land to Core Foundation country. We use __bridge_retained to make sure ARC does not release and deallocate the object while we are working with it. This kind of bridging cast retains the object, so to prevent leaks, it must be followed with a corresponding CFRelease somewhere. SecItemCopyMatching definitely will not release the query for us, so if we use a retained bridge, then we need to release the resulting Core Foundation object ourself. (Which we do in line 4.)
  • Lines 2, 3, and 4 are pure C code using Core Foundation types, so ARC will have nothing to do or complain about them.
  • In line 5, we tell ARC that SecItemCopyMatching has created its result with a retain count of 1, which we are responsible for releasing. (We know this because it has "Copy" in its name.) __bridge_transfer lets ARC know about this responsibility, so it will be able to do it for us automatically.
  • Don't cast the immutable Core Foundation dictionary returned by SecItemCopyMatching to NSMutableDictionary; that's just wrong. Also, it is against general Cocoa style conventions that buildSearchQuery returns an NSMutableDictionary. Simple NSDictionarys would work fine in both cases.

这里是 __ bridge_retained 需要后跟一个 CFRelease ,而复制或创建函数必须使用 __ bridge_transfer 转换为可可土地。

The rule of thumb here is that __bridge_retained needs to be followed by a CFRelease, while the result from a "Copy" or "Create" function must be cast into Cocoa-land using __bridge_transfer.

这篇关于iPhone从钥匙串提取数据字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆