2013-08-07 2 views
1

Update:Краш на второй адресной книги (контакты) подстановки

Я считаю, что проблема лежит где-то в том, как я храню ссылки на 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. 

ответ

0
- (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]; 
    } 
} 
+0

Да, я возвращаю «НЕТ». – devios1

1

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

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

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

Смежные вопросы