2011-01-18 16 views
6

Ho una perdita di memoria nel codice successivo. Mi sono ispirato allo here e questa è una parte dell'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; 

}

Lo strumento Leak dice che sta perdendo in questa linea:

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

dirmi come avrei potuto risolvere questo problema.

risposta

6

Il tuo metodo è a volte restituisce un'istanza con il conteggio dei ritegni +1 e probabilmente non la rilascerai nel resto del codice. Stai ritornando con retain count con +1 se viene chiamato SecItemCopyMatching, ma se publicKey è impostato, la tua funzione restituisce un valore con retain count + -0 che è negativo.

È necessario assicurarsi di restituire sempre con lo stesso conteggio. In questo caso, mi piacerebbe fare:

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

Poi ogni visitatore al vostro metodo deve fare in modo di CFRelease il valore ... ma che sarebbe violare la get regola (deve restituire mantenere count + - 0), quindi forse sarebbe una buona idea rinominare il metodo.

+0

Ma che dire di SecItemCopyMatching, lo strumento Leak dice che questo è il punto in cui si verifica la perdita. –

+1

Sì, perché non si sta 'CFRelease' il valore che viene restituito da' getPublicKeyRef' nel proprio codice usa 'getPublicKeyRef'. E Instruments ti dice dove è stato assegnato. Pertanto, devi 'CFRelease' quel valore da qualche parte. Ma poi si arresterebbe in modo anomalo se 'publicKey' è già impostato, motivo per cui è necessario mantenerlo in modo che il metodo restituisca sempre un valore con un conteggio dei ritardi di +1. – DarkDust

+0

Guarda questo è l'unico posto da dove viene chiamato, non è stato rilasciato lì? status = SecKeyEncrypt ([sé getPublicKeyRef], IMBOTTITURA, plainBuffer, dimensioni, & cipherBuffer [0], & cipherBufferSize ); –