我在 SecItemCopyMatching 上发现了内存泄漏。在对 SF 进行调查后,我找到了解决方案:
__block NSString *certificateName = nil;
SecKeychainRef keychain;
SecKeychainCopyDefault(&keychain);
NSMutableDictionary *attributeQuery = [NSMutableDictionary dictionary];
[attributeQuery setObject: (id) kSecClassIdentity forKey:(__bridge_transfer id) kSecClass];
[attributeQuery setObject: (id) kCFBooleanTrue forKey:(__bridge_transfer id) kSecReturnRef];
[attributeQuery setObject: (id) kSecMatchLimitAll forKey:(__bridge_transfer id) kSecMatchLimit];
CFTypeRef attrResult = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) attributeQuery,(CFTypeRef *) &attrResult);<------- here is a leak according Instruments
if (status != errSecItemNotFound) {
NSArray *attributeResult = (__bridge_transfer NSArray *)attrResult;
[attributeResult enumerateObjectsUsingBlock:^(id identityFromArray, NSUInteger idx, BOOL *stop) {
OSStatus status;
SecCertificateRef cert = NULL;
status = SecIdentityCopyCertificate((__bridge SecIdentityRef)identityFromArray, &cert);
if (!status)
{
或其他解决方案:
NSMutableDictionary *attributeQuery = [NSMutableDictionary dictionary];
[attributeQuery setObject: (id) kSecClassIdentity forKey:(__bridge_transfer id) kSecClass];
[attributeQuery setObject: (id) kCFBooleanTrue forKey:(__bridge_transfer id) kSecReturnRef];
[attributeQuery setObject: (id) kSecMatchLimitAll forKey:(__bridge_transfer id) kSecMatchLimit];
CFTypeRef attrResult = NULL;
CFDictionaryRef cfquery = (__bridge_retained CFDictionaryRef)attributeQuery;
OSStatus status = SecItemCopyMatching(cfquery,(CFTypeRef *) &attrResult);<------- here is a leak according Instruments
if (status != errSecItemNotFound) {
NSArray *attributeResult = (__bridge_transfer NSArray *)attrResult;
[attributeResult enumerateObjectsUsingBlock:^(id identityFromArray, NSUInteger idx, BOOL *stop) {
OSStatus status;
SecCertificateRef cert = NULL;
status = SecIdentityCopyCertificate((__bridge SecIdentityRef)identityFromArray, &cert);
if (!status)
{
char *nameBuf = NULL;
CFStringRef nameRef = NULL;
OSStatus statusNew = SecCertificateInferLabel(cert, &nameRef);
.....
CFRelease(cfquery)
但是他们两个仍然对我泄漏。
任何其他想法