2011-01-18 13 views
6

Tengo una pérdida de memoria en el código siguiente. Me inspiré desde here y esto es parte del algoritmo RSA.SecItemCopyMatching memory leaking

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

}

El instrumento de fugas dice que hay una fuga en esta línea:

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

por favor dígame cómo puedo solucionar esto.

Respuesta

6

Su método es veces devolviendo una instancia con retención de recuento +1 y lo más probable es que no la libere en el resto de su código. Usted está regresando con retención de conteo +1 si se llama a SecItemCopyMatching, pero si publicKey está configurado, entonces su función devuelve un valor con retención de conteo + -0 que es malo.

Debe asegurarse de regresar siempre con el mismo conteo de retención. En este caso, lo haría:

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

Entonces, cada persona que llama a su método debe asegurarse de que el valor CFRelease ... pero eso sería violar la obtener regla (que debería volver a retener recuento + - 0), así que tal vez sería una buena idea cambiar el nombre del método.

+0

Pero qué pasa con SecItemCopyMatching, el instrumento de fuga dice que este es el lugar donde ocurre la fuga. –

+1

Sí, porque no está 'CFRelease' ing el valor que devuelve' getPublicKeyRef' en su código utiliza 'getPublicKeyRef'. E Instrumentos le dice dónde fue asignado. Por lo tanto, debe 'CFRelease' ese valor en alguna parte. Pero luego se bloqueará si 'publicKey' ya está configurado, por lo que debe conservarlo también para que su método siempre devuelva un valor con un conteo de retención de +1. – DarkDust

+0

Mire, este es el único lugar desde donde se lo llama, ¿no se lo lanzó allí? estado = SecKeyEncrypt ([libre getPublicKeyRef], relleno, plainBuffer, tamaño, y cipherBuffer [0], y cipherBufferSize ); –