泄漏这种方法

时间:2014-04-18 09:12:01

标签: ios memory-leaks core-foundation

泄漏工具显示泄漏的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;
}

但我看不出这种泄漏方法有什么问题。

2 个答案:

答案 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;
相关问题