Утечка ABAddressBookRef в iOS

#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?