CFRelease(addressBook) приводит к сбою моего приложения для iOS

- (void)tableView:(UITableView *)tableView 
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = indexPath.row;

    if (row == NSNotFound)
        return;

    if (call.uid != kABRecordInvalidID)
    {
        ABAddressBookRef addressBook = ABAddressBookCreate();

        ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook,
                                                                call.uid);


       // CFRelease(addressBook);// commenting out this makes the program not crash

}
}

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

Итак, представьте, что я нажимаю кнопку аксессуара для uitableview. Я делаю то, что должен, и возвращаюсь к исходному окну, затем снова нажимаю кнопку аксессуара uitableview, и программа вылетает с этой ошибкой:

-[Не сохранен тип]: сообщение отправлено на освобожденный экземпляр 0x618d810.


person j2emanue    schedule 21.08.2012    source источник


Ответы (1)


Адресная книга не является причиной сбоя (напрямую).

Вы не сохраняете своего человека, вы просто получаете ссылку на него/нее. Попробуйте использовать CFRetain на себе.

ABAddressBookRef addressBook = ABAddressBookCreate();
ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook,
                                                        call.uid);
CFRetain(person);
CFRelease(addressBook);
person deanWombourne    schedule 21.08.2012
comment
Привет Дин, ты решил проблему и моя похвала. Я соглашусь через секунду, но не могли бы вы помочь мне понять, почему я должен удержать этого человека. После того, как я вернусь к методу, почему ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, call.uid); не хранить человека? почему я должен сохранять его, когда метод делегата вызывается всякий раз, когда пользователь нажимает кнопку аксессуара, поэтому он должен просто снова схватить человека и продолжить, как в первый раз, я понятия не имею, почему я должен сохранить человека .. вы можете помочь - person j2emanue; 21.08.2012
comment
Это не имеет смысла, потому что у меня есть адресная книга, которую я создал, я использую эту адресную книгу, чтобы получить запись о человеке, которую я хочу, и сохранить ее в переменной человека. если я отпущу адресную книгу, почему переменная person вызывает сбой??? - person j2emanue; 21.08.2012
comment
Вам нужно лучше понять Core Foundation. Когда вы получаете что-то с Get в имени, это означает, что у вас есть временный указатель на объект. Все, что возвращает Get, является временным. Create, с другой стороны, означает, что вы являетесь владельцем этого нового объекта. - person David H; 22.08.2012
comment
@DavidH абсолютно прав, но я не думаю, что он зашел достаточно далеко - вам нужно лучше понять управление памятью и подсчет ссылок - только потому, что вы знаете, где что-то находится сейчас, не означает, что это будет там навсегда, это может уйти. Вы говорите iOS не отпускать его, вызывая retain (или CFRetain в данном случае). Прочитайте это: developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ (и прямоугольник документации по управлению памятью там) - person deanWombourne; 22.08.2012