【问题标题】:SecItemCopyMatching memory leakingSecItemCopyMatching 内存泄漏
【发布时间】:2011-01-18 09:27:06
【问题描述】:

我在下一个代码中有内存泄漏。我的灵感来自here,这是 RSA 算法的一部分。

- (SecKeyRef)getPublicKeyRef {
OSStatus resultCode = noErr;
SecKeyRef publicKeyReference = NULL;

if(publicKey == NULL) {
    NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];

    NSData *publicTag = [NSData dataWithBytes:publicKeyIdentifier

                                       length:strlen((const char *)publicKeyIdentifier)]; 

    // Set the public key query dictionary.
    [queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass];
    [queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag];

    [queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];

    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];

    // Get the key.     
    resultCode = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyReference);
   // NSLog(@"getPublicKey: result code: %d", resultCode);

    if(resultCode != noErr)
    {
        publicKeyReference = NULL;
    }

    // [publicTag release];
    [queryPublicKey release];
} else {
    publicKeyReference = publicKey;
}

return publicKeyReference;

}

Leak 仪器说它在这一行中泄漏:

resultCode = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyReference);

请告诉我如何解决这个问题。

【问题讨论】:

    标签: iphone security rsa


    【解决方案1】:

    您的方法有时会返回一个保留计数 +1 的实例,而您很可能不会在其余代码中释放它。如果调用 SecItemCopyMatching,您将返回保留计数 +1,但如果设置了 publicKey,那么您的函数将返回一个保留计数 +-0 的值,这是不好的。

    您需要确保始终以相同的保留计数返回。在这种情况下,我会这样做:

    } else {
        publicKeyReference = publicKey;
        CFRetain(publicKeyReference);
    }
    

    那么每个调用你的方法的人都必须确保CFRelease这个值......但这违反了get规则(它应该返回retain count +-0),所以也许它然后重命名该方法是个好主意。

    【讨论】:

    • 但是SecItemCopyMatching呢,泄漏仪器说这是发生泄漏的地方。
    • 是的,因为您不是 CFRelease ,您的代码中由 getPublicKeyRef 返回的值使用 getPublicKeyRef。 Instruments 会告诉您分配的位置。因此,您必须在某处 CFRelease 该值。但是如果 publicKey 已经设置,它会崩溃,这就是为什么你必须保留它,这样你的方法总是返回一个保留计数为 +1 的值。
    • 看这里是唯一被调用的地方,不是发布在那里吗? status = SecKeyEncrypt([self getPublicKeyRef], PADDING, plainBuffer, size, &cipherBuffer[0], &cipherBufferSize);
    • 遇到了同样的问题,奇怪的是文档没有特别提到返回的 CFDictionaryRef 的保留计数为 +1。无论如何,在与您类似的代码中,如果返回状态为 noErr 并且一切正常,我只需调用 [publicKeyReference autorelease]。 :)
    • 谢谢 DarkDust,你拯救了我的一天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2013-01-20
    • 2011-10-31
    • 2019-08-10
    • 2013-06-24
    • 2011-03-22
    相关资源
    最近更新 更多