2010-04-10 37 views
5

Tôi bị chặn.Đọc địa chỉ email từ các địa chỉ liên hệ không thành công với sự cố bộ nhớ lạ

Tôi đang cố gắng lấy danh sách tất cả địa chỉ email mà một người có. Tôi đang sử dụng số ABPeoplePickerNavigationController để chọn người, mọi thứ đều ổn. Tôi đang thiết của tôi

ABRecordRef personDealingWith; 

từ lập luận person để

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { 

và mọi thứ dường như tinh cho đến thời điểm này. Lần đầu tiên mã sau thực hiện, tất cả đều tốt. Khi sau đó chạy, tôi có thể gặp sự cố. Trước tiên, mã:

// following line seems to make the difference (issue 1) 
// NSLog(@"%d", ABMultiValueGetCount(ABRecordCopyValue(personDealingWith, kABPersonEmailProperty))); 

// construct array of emails 
ABMultiValueRef multi = ABRecordCopyValue(personDealingWith, kABPersonEmailProperty); 
CFIndex emailCount = ABMultiValueGetCount(multi); 

if (emailCount > 0) { 
    // collect all emails in array 
    for (CFIndex i = 0; i < emailCount; i++) { 
     CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i); 
     [emailArray addObject:(NSString *)emailRef]; 
     CFRelease(emailRef); 
    } 
} 

// following line also matters (issue 2) 
CFRelease(multi); 

Nếu được biên dịch dưới dạng văn bản, không có lỗi hoặc lỗi phân tích tĩnh. Sự cố này xảy ra với số điện thoại

*** -[Not A Type retain]: message sent to deallocated instance 0x4e9dc60

.

Nhưng hãy đợi, còn nhiều hơn nữa! Tôi có thể sửa nó theo một trong hai cách.

Thứ nhất, tôi có thể bỏ ghi chú NSLog ở đầu chức năng. Tôi bị rò rỉ từ ABRecordCopyValue của NSLog mỗi lần, nhưng mã dường như chạy tốt.

Ngoài ra, tôi có thể nhận xét ra các

CFRelease(multi); 

vào cuối, mà thực hiện chính xác những điều tương tự. Lỗi biên dịch tĩnh, nhưng đang chạy mã.

Vì vậy, không bị rò rỉ, chức năng này bị treo. Để ngăn chặn một vụ tai nạn, tôi cần phải xuất huyết bộ nhớ. Không phải là một giải pháp tuyệt vời.

Có ai có thể chỉ ra những gì đang diễn ra?

Trả lời

13

Hóa ra là tôi đã không lưu trữ đúng số ABRecordRef personDealingWith var. Tôi vẫn không chắc chắn làm thế nào để làm điều đó đúng, nhưng thay vì có các chức năng trong một thói quen khác (thực hiện sau), tôi đang làm grunt-công việc trong phương pháp đại biểu, và sử dụng kết quả có nguồn gốc tại giải trí của tôi. Quy trình mới (hoạt động):

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { 
    // as soon as they select someone, return 
    personDealingWithFullName = (NSString *)ABRecordCopyCompositeName(person); 
    personDealingWithFirstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    // construct array of emails 
    [personDealingWithEmails removeAllObjects]; 
    ABMutableMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty); 
    if (ABMultiValueGetCount(multi) > 0) { 
     // collect all emails in array 
     for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) { 
      CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i); 
      [personDealingWithEmails addObject:(NSString *)emailRef]; 
      CFRelease(emailRef); 
     } 
    } 
    CFRelease(multi); 
    return NO; 
} 
0

Tôi đã gặp sự cố tương tự. Vấn đề có thể nằm ở cách bạn thiết lập của bạn

ABRecordRef personDealingWith; 

Dường như bạn không thể chỉ làm:

ABRecordRef personDealingWith = person; 

Vì personDealingWith vẫn null. Thay vào đó, những gì tôi đã làm là:

ABRecordID personID = ABRecordGetRecordID(person); 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 
personDealingWith = ABAddressBookGetPersonWithRecordID(addressBook, personID); 
Các vấn đề liên quan