#ios #memory-leaks
#iOS #утечки памяти
Вопрос:
Я анализирую адресную книгу в iOS, но инструмент утечки сообщает о больших утечках памяти, кажется, я не могу отследить проблему
Сначала я создаю адресную книгу.
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
Я подозреваю, что это утечка, но ABAddressBookRef и CFArrayRef автоматически освобождаются, верно?
Остальная часть моего кода приведена ниже..
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray *List = [[NSMutableArray alloc] init];
for (int i = 0; i < nPeople; i ) {
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
NSNumber *recordId = [NSNumber numberWithInteger:ABRecordGetRecordID(ref)];
CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
CFDataRef imgData = ABPersonCopyImageData(ref);
ABMutableMultiValueRef multi = ABMultiValueCreateMutable(kABMultiStringPropertyType);
multi = ABRecordCopyValue(ref,kABPersonEmailProperty);
for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i ) {
CFStringRef email, emailLabel;
emailLabel = ABMultiValueCopyLabelAtIndex(multi, i);
email = ABMultiValueCopyValueAtIndex(multi, i);
NSString *emails = [NSString stringWithFormat: @"%@", (NSString *)email];
if (emails)
{
NSMutableDictionary *addDict = [[NSMutableDictionary alloc] init];
[addDict addObject:emails forKey:@"email"];
[List addObject:addDict];
[addDict release];
}
CFRelease(email);
CFRelease(emailLabel);
}
if (firstName) {
CFRelease(firstName);
}
if (lastName) {
CFRelease(lastName);
}
if (imgData) {
CFRelease(imgData);
}
if (ref) {
CFRelease(ref);
}
CFRelease(multi);
}
//do something with list
[List release];
Ответ №1:
Хорошо, это работает и не протекает
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray *List = [[NSMutableArray alloc] init];
for (int x = 0; x < nPeople; x ) {
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, x);
ABMultiValueRef emailMultiValue = ABRecordCopyValue(ref, kABPersonEmailProperty);
NSArray *emailAddresses = [(NSArray *)ABMultiValueCopyArrayOfAllValues(emailMultiValue) autorelease];
for (int i = 0; i < [emailAddresses count]; i ) {
NSString *emails = [emailAddresses objectAtIndex:i];
if (emails)
{
NSMutableDictionary *addDict = [[NSMutableDictionary alloc] init];
[addDict addObject:emails forKey:@"email"];
[List addObject:addDict];
[addDict release];
}
}
if (emailMultiValue)
{
CFRelease(emailMultiValue);
}
if (ref) {
CFRelease(ref);
}
}
//do something with list
[List release];
CFRelease(allPeople);
Ответ №2:
На самом деле, чтобы устранить все утечки, вам также необходимо выпустить ABAddressBookRef — просто следуйте рекомендациям Core Foundation по именованию — вы получили ссылку, используя «ABAddressBookCreate()», и любая функция с Create или Copy должна быть выпущена.
Ответ №3:
Ошибка CFErrorRef = NULL;
ABAddressBookRef addressbk=ABAddressBookCreateWithOptions(NULL, amp;error);
if (addressbk != nil)
{
NSLog(@"Succesful.");
NSArray *allContacts=(NSArray *)ABAddressBookCopyArrayOfAllPeople(addressbk); //type casting nsarray from CFArrayRef
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i )
{
Category *mCategory = [[Category alloc]init];
ABRecordRef contactPerson = ( ABRecordRef)allContacts[i];
NSString *firstName = ( NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = ( NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
mCategory.firstName = firstName;
mCategory.lastName = lastName;
mCategory.fullName = fullName;
//email
ABMultiValueRef emails = ABRecordCopyValue(contactPerson, kABPersonEmailProperty);
NSUInteger j = 0;
for (j = 0; j < ABMultiValueGetCount(emails); j )
{
NSString *email = ( NSString *)ABMultiValueCopyValueAtIndex(emails, j);
if (j == 0)
{
mCategory.homeEmail = email;
NSLog(@"mCategory.homeEmail = %@ ", mCategory.homeEmail);
}
else if (j==1)
mCategory.workEmail = email;
}
[self.arrAddress addObject:mCategory];
[mCategory release];
mCategory=nil;
}
}
CFRelease(addressbk);
Комментарии:
1. Разве вы не должны явно освобождать объект ’email’ типа ABMultiValueRef?