Сбой при поиске второй адресной книги (контактов)

Обновить:

Я считаю, что проблема заключается где-то в том, как я храню ссылку на ABRecordRef, Я в настоящее время просто держусь за ценность, как доставлено peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier: и не CFRetainили что-то в этом роде. Из документации неясно, нужно ли ее сохранить.


Я работаю над приложением для iPhone, которое взаимодействует с адресной книгой с использованием платформ AddressBook и AddressBookUI. Я использую ABPeoplePickerNavigationController представить список контактов пользователю на выбор, и я получаю результат ABRecordRef в качестве переменной экземпляра в пользовательском классе.

Это все работает нормально при первом использовании. Однако во второй раз, когда я выбираю кого-то из контактов (даже другого человека), мое приложение взрывается EXC_BAD_ACCESS по вызову ABRecordCopyValue, Я регистрирую указатели, и они определенно отличаются каждый раз при выборе контакта (даже если один и тот же контакт дважды).

Я не понимаю, как эта ссылка может быть освобождена. Утечка памяти, конечно, но почему она работает нормально в первый раз, а не во второй?

Вот фактический звонок, от которого он умирает:

- (NSString*)displayName {
    return CFBridgingRelease( ABRecordCopyValue( self.contact, kABPersonFirstNameProperty ) );
}

Вот некоторые выходные данные отладки, если это вообще полезно:

Printing description of self->_contact:
(ABRecordRef) _contact = 0x1f582dc0

(lldb) expr (CFTypeRef)ABRecordCopyValue(self.contact, kABPersonFirstNameProperty)
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0xd1f57cc1).
The process has been returned to the state before execution.

2 ответа

Оказывается, все, что мне нужно было CFRetain( person ) и все счастливы, снова повезло. Я также добавил dealloc в мой класс, чтобы очистить указатель, когда объект уходит:

- (void)dealloc {
    CFRelease( _contact );
}

Мой код теперь работает без сбоев, и статический анализатор счастлив (не то, что он все равно обнаружил утечку).

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    [self displayPerson:person];
    [self dismissViewControllerAnimated:YES completion:nil];

    return NO;
}

ты возвращаешься НЕТ?

Попробуйте проверить, существует ли значение, может быть

т.е.

- (void)displayPerson:(ABRecordRef)person
{
    NSString* companyName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
    NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSString* display = @"";

    if (companyName) {
        display = companyName;
    } else if (name) {
        display = name;
    } else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"No Details For Contact"
                                                            message:@"Please update contact with company and/or first name"
                                                           delegate:nil
                                                  cancelButtonTitle:@"Dismiss"
                                                  otherButtonTitles:nil];
        [alertView show];
    }
}
Другие вопросы по тегам