Приложение аварийно завершает работу каждый второй раз, когда в настройке навигационного контроллера выбирается строка таблицы.

Сначала отказ от ответственности: я новичок в Objective-C и модели сохранения. Последние пять лет я разрабатывал в среде .NET со сборщиком мусора, поэтому я был избалован. Я еще учусь.

У меня происходит сбой приложения для iPhone с EXC_BAD_ACCESS. Это происходит в настройках навигационного контроллера/таблицы. Когда я выбираю строку в первый раз, проблем нет. Он переключается в дочерний контроллер без проблем. Я возвращаюсь и снова выбираю ту же строку. Затем программа продолжает аварийно завершать работу. Каждая вторая строка работает нормально, но каждый секундный доступ к строке происходит сбой.

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

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


person Community    schedule 24.03.2010    source источник
comment
Как вы поддерживаете массив в дочернем контроллере? Это через свойство, и если да, то используете ли вы сохранение, назначение или копирование? Кроме того, я не думаю, что это должна быть вики сообщества.   -  person Brandon Bodnar    schedule 25.03.2010
comment
Извините, я думал, что вики сообщества означает что-то другое, чем это было на самом деле. Массив в дочернем свойстве, безусловно, является свойством, и он сохраняется. Вот почему я не понял в первую очередь. NSZombieEnabled (см. ниже) показал мне, что метод был отправлен в освобожденный экземпляр, поэтому я предполагаю, что я выпустил его в ближайшее время. Я до сих пор не прибил его, хотя.   -  person Thaurin    schedule 25.03.2010


Ответы (2)


Включить NSZombies.

http://www.cocoadev.com/index.pl?NSZombieEnabled

Это поможет вам идентифицировать объект, который перевыпускается (вероятно, что происходит).

person xyzzycoder    schedule 24.03.2010
comment
Мое приложение все еще зависало и возвращалось к трамплину в симуляторе. Разве это не то, что не должно происходить при включении этого параметра? Однако я получил хорошую строку в консоли отладчика, говорящую мне, какой метод был отправлен в освобожденный экземпляр (isEqualToString) - person Thaurin; 25.03.2010
comment
Убедитесь, что вы запускаете отладку и устанавливаете точку останова при повышении. В консоли (вам понадобится функция повышения при появлении запроса): b поднять - person xyzzycoder; 25.03.2010

Итак... [UINavigationController pushViewController] не сохраняет, не так ли? ;) Что я сделал, так это инициализировал/распределил контроллер, который должен был быть помещен в стек навигации, поместил его и затем освободил. Я думал, что навигационный контроллер сохранит контроллер. Судя по всему, это не так. Очевидно, что это сработало в первый раз, но не во второй раз. Думаю, именно здесь память действительно освободилась. Включение зомби показало, что он получал сообщения (от сеттеров) на освобожденный объект.

Почему я думал, что pushViewController сохранит контроллер? Я не знаю; Я думаю, что запутался, думая, что если вы выделяете его, вы также несете ответственность за его освобождение. Я как-то подумал, что после нажатия, это будет ответственность навигационного контроллера. Кажется, я был неправ.

Я все еще учусь чувствовать это (злой C # и сборка мусора поджарили мой разум!). У кого-нибудь есть что добавить?

Чтобы проиллюстрировать, это кажется неправильным:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSUInteger section = [indexPath section];
 NSUInteger row = [indexPath row];

 if (selectionController == nil)
 {
  selectionController =
   [[ConfigSelectionViewController alloc] initWithStyle:UITableViewStyleGrouped];
 }

 NSString *title = [self titleForSection:section row:row];
 NSString *key = [self keyForSection:section row:row];

 selectionController.configKey = key;
 selectionController.title = title;

 NSArray *listItems = [self itemsForSection:section row:row];
 selectionController.list = listItems;

 [self.navigationController pushViewController:selectionController animated:YES];

        // DON'T DO THIS!
        [selectionController release];


}
person Community    schedule 29.03.2010
comment
Это неправильно. UINavigationController сохраняется при нажатии нового контроллера представления. Где-то в вашем коде есть ошибка! - person Rengers; 30.03.2010
comment
Ты абсолютно прав. Я обнаружил это сегодня утром. На самом деле я освобождал объект в массиве через указатель на него, а это вовсе не было намерением! Я по глупости думал, что указатель сохраняет его. Итак, проблема решена. Но спасибо за подтверждение. - person Thaurin; 30.03.2010