Сбой при поиске второй адресной книги (контактов)
Обновить:
Я считаю, что проблема заключается где-то в том, как я храню ссылку на 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];
}
}