2011-12-29 39 views
5

Ben kimlik doğrulaması için kullanıcı şifresini depolamak için Apple'ın örnek koddan KeyChainItemWrapper kullanıyorum ama şifreyi ayarlamak için çağırdığınızda:Bellek Sızıntısı KeychainItemWrapper

[keychain setObject:passwordField.text forKey:(id)kSecValueData]; 

Bu gömleğimi tüm bellek sızıntıları geçiyor . bu KeyChainItemWrapper.m içinde 274 satıra geri izleri görünüşte sorun:

if (SecItemCopyMatching((CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr) 
{ 

nasıl düzeltebilirim ediyorum ve gelecekte Apple örnek kod ile çalışırken daha dikkatli olmalıdır?

Not: Daha fazla kod yayınlayabilirim, ancak bu satırları Aletleri kullanarak daralttım ve örnek kod tam olarak herhangi bir geliştiriciye açık.

cevap

5

KeyChainItemWrapper koduna bakarak, bu satırın bir bellek sızıntısı olduğunu kabul ediyorum. writeToKeychain'un sonunda [attributes release]'u kaçırdılar. Geri dönen referans nesnesini doğru şekilde nasıl serbest bıraktıklarına dair örnekler için bu dosyada SecItemCopyMatching() numaralı tüm çağrılara bakın.

Bu sayfanın altındaki "Bu iyi, ama ..." bağlantısını kullanıp hatayı not edin.

+0

Tam olarak sorunun nerede olduğuydu. Sadece [özellikler sürümünü] ekle; bağlanan işlev fişlerinin sonuna. Bu hata, önerdiğiniz gibi Apple'a bildirildi. – Serendipity

+1

Wow - örnek kodun devam ettiği sürece, KeychainItemWrapper'ın en kötüsü olduğunu düşünüyorum! autoreleases her yerde, yukarıda da dahil olmak üzere en az 2 bilinen bellek sızıntısı, ve başka bir keychainItemData başlatılıyor ... – npellow

+0

npellow, autoreleases ile ilgili sorun nedir? Sadece bir noktada serbest bırakıyorlar.Apple bunları sık sık kullanır. Aslında, biz kendi programımızın nasıl yapılacağını istemek için –

0

- (void) resetKeychainItem'da başka bir sızıntı buldum.

O

self.pKeychainItemData = [[[NSMutableDictionary alloc] init] autorelease]; olmalıdır.

+2

neden 'self.pKeychainItemData = [NSMutableDictionary dictionary];'? Çok daha temiz ... –

3

Statik analiz, KeyChainItemWrapper.m adresindeki yöntem resetKeychainItem, satır 191'deki olası bir nesnenin sızıntısını bildiriyor. Şaşırtıcı bir şekilde, yukarıda belirtilen alanda potansiyel bir sızıntı olmadığını rapor etmekteyim, ancak önerilen nesnenin serbest bırakılmasını ve doğruluğunu ekledim. İşte

sızıntısı ile kod rapor ediliyor ise:

- (void)resetKeychainItem 
{ 
    ... 
    // Default attributes for keychain item. 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrAccount]; // <-- Potential leak of an object 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrLabel]; 
    [keychainItemData setObject:@"" forKey:(id)kSecAttrDescription]; 

    // Default data for keychain item. 
    [keychainItemData setObject:@"" forKey:(id)kSecValueData]; 
} 

Bu sorun "" @ boş dize üzerinde rapor ediliyor. Bu sorunu denemek ve düzeltmek için çeşitli kod uygulamalarını denedim, ancak hiçbir şey işe yaramıyor.

Bu yanlış pozitif midir?

Güncelleme: Göndermeden hemen sonra hatayı izlemek için uyarıyı çift tıklayabileceğimi farkettim.

Bu uyarı sözlük tahsis edilmesi için yukarıda hattına bağlanmaktadır:

if (!keychainItemData) 
{ 
    self.keychainItemData = [[[NSMutableDictionary alloc] init] autorelease]; 
} 

analiz uyarı artık mevcut değildir:

if (!keychainItemData) 
{ 
    self.keychainItemData = [[NSMutableDictionary alloc] init]; 
} 

aşağıdaki kod değiştirildi.