泄漏工具显示泄漏的NSCFData
对象数量,堆栈跟踪显然在我的应用方法边界的末尾包含以下方法。
NSData* SAKeychainGetValue(NSString *key)
{
NSMutableDictionary *searchDictionary = SAGetKeychainSearchDictionary(key);
[searchDictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[searchDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
CFDataRef value = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, (CFTypeRef *)&value);
if (status != errSecSuccess && status != errSecItemNotFound)
{
NSLog(@"failed to get key %@ with error %ld.", key, (long)status);
}
return (__bridge NSData*)value;
}
但我看不出这种泄漏方法有什么问题。
答案 0 :(得分:1)
您应该在__bridge_transfer
中使用__bridge
代替(__bridge NSData*)value
。
应该释放SecItemCopyMatching
方法返回的值(复制意味着应该在Apple命名约定中释放值返回),因此您应该将所有权转移到ARC。
答案 1 :(得分:1)
您可以尝试使用静态分析器来解决此类问题CMD+Shift+B
是默认快捷方式
但是你正在混合你的桥梁
NSData* SAKeychainGetValue(NSString *key)
{
NSMutableDictionary *searchDictionary = SAGetKeychainSearchDictionary(key);
[searchDictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[searchDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
CFDataRef value = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, (CFTypeRef *)&value);
if (status != errSecSuccess && status != errSecItemNotFound)
{
NSLog(@"failed to get key %@ with error %ld.", key, (long)status);
}
return (__bridge_transfer NSData*)value;
}
您也可以直接使用NSData
:
NSData *value = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, (CFTypeRef *)&value);
...
return value;