2011-12-29 26 views
5

Tôi đang sử dụng KeyChainItemWrapper từ mẫu mã của Apple để lưu trữ mật khẩu người dùng để xác thực, nhưng khi tôi gọi nó là để thiết lập mật khẩu:Memory Leak trong iOS KeychainItemWrapper

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

Nó banh rò rỉ bộ nhớ trên khắp áo của tôi . Vấn đề rõ ràng dấu vết trở lại dòng 274 trong KeyChainItemWrapper.m, mà là thế này:

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

Làm thế nào tôi có thể khắc phục điều này, và tôi nên cẩn thận hơn khi làm việc với Apple mẫu mã trong tương lai?

Lưu ý: Tôi có thể đăng thêm mã, nhưng tôi đã thu hẹp sự cố xuống dòng này bằng cách sử dụng Công cụ và mã mẫu đầy đủ sẵn có cho bất kỳ nhà phát triển nào.

Trả lời

5

Nhìn vào mã cho KeyChainItemWrapper, tôi đồng ý rằng dòng này là rò rỉ bộ nhớ. Họ đã bỏ lỡ số [attributes release] ở cuối writeToKeychain. Xem tất cả các cuộc gọi khác tới SecItemCopyMatching() trong tệp này để biết các ví dụ về cách chúng phát hành chính xác đối tượng được trả về theo tham chiếu.

Tôi sẽ sử dụng liên kết "Tốt, nhưng ..." ở cuối trang này để lưu ý lỗi.

+0

Đó chính xác là nơi xảy ra sự cố. Chỉ cần thêm [phát hành thuộc tính]; đến cuối của các chức năng cắm liên kết đó. Lỗi này đã được báo cáo cho Apple như bạn đã đề xuất. – Serendipity

+1

Wow - theo như mã mẫu đi, tôi nghĩ KeychainItemWrapper là một trong những điều tồi tệ nhất hiện có! autoreleases ở khắp mọi nơi, ít nhất 2 rò rỉ bộ nhớ đã biết, bao gồm cả ở trên, và một cái khác khởi tạo keychainItemData ... – npellow

+0

npellow, có gì sai với autoreleases? Họ chỉ phát hành tại một số điểm.Apple sử dụng chúng thường xuyên. Thực ra, cách họ muốn chúng ta lập trình –

0

Tôi tìm thấy một lỗ hổng khác trong - (void) resetKeychainItem.

Phải là

self.pKeychainItemData = [[[NSMutableDictionary alloc] init] autorelease];.

+2

tại sao không 'self.pKeychainItemData = [NSMutableDictionary dictionary];'? Sạch hơn nhiều ... –

3

Phân tích tĩnh đang báo cáo sự rò rỉ tiềm ẩn của đối tượng trong phương thức resetKeychainItem, dòng 191, của KeyChainItemWrapper.m. Đáng ngạc nhiên, nó không báo cáo một sự rò rỉ tiềm ẩn trong khu vực được đề cập ở trên, mặc dù tôi đã thêm bản phát hành của đối tượng như được đề xuất và cho tính chính xác.

Đây là mã với rò rỉ được báo cáo:

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

vấn đề này đã được báo cáo về chuỗi rỗng @ "". Tôi đã thử một loạt các triển khai mã để thử và "khắc phục" vấn đề này, nhưng không có gì xuất hiện để hoạt động.

Đây có phải là dương tính giả không?

Cập nhật: Ngay sau khi đăng, tôi nhận ra rằng tôi có thể nhấp đúp vào cảnh báo để theo dõi lỗi.

Cảnh báo này là do những dòng trên nó phân bổ từ điển:

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

tôi đã thay đổi mã như sau:

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

Cảnh báo phân tích là không còn hiện diện.