tableviewcontroller с дочерним элементом detailViewController падает с загадочным EXC_BAD_ACCESS

У меня есть родительский контроллер табличного представления со свойством контроллера подробного представления только для чтения, которое лениво создает экземпляр контроллера подробного представления. Если я нахожусь на iphone/ipod, я настраиваю и нажимаю контроллер подробного представления, когда выбирается элемент в таблице. Когда вид подробностей виден, и я дважды щелкаю назад в контроллере навигации, контроллер деталей, а затем родительский контроллер выталкиваются, и вызывается родительская Dealloc. Когда Dealloc родителя достигает строки, где я вызываю [detailViewController release], я получаю сбой с EXC_BAD_ACCESS от навигационного контроллера. Это наводит меня на мысль, что моя проблема связана с управлением памятью в detailViewController, но отладка с помощью NSZombies не выявила проблем. (Комментирование строки [detailViewController release] устраняет сбой, но тогда у меня никогда не будет выпуска, чтобы сбалансировать выделение памяти в detailViewController -- утечка памяти) Есть идеи, почему я получаю этот сбой?

РЕДАКТИРОВАТЬ: вот трассировка стека для сбоя:

Program received signal:  “EXC_BAD_ACCESS”.
(gdb) bt
#0  0x01046a63 in objc_msgSend ()
#1  0x0a9d72a0 in ?? ()
#2  0x0000cb4c in -[MyTableViewController dealloc] (self=0xa956840, _cmd=0x127a9d6) at /Users/nick/Documents/MyApp/Classes/MyTableViewController.m:290
#3  0x00390f1d in -[UINavigationController setDisappearingViewController:] ()
#4  0x0038e4f6 in -[UINavigationController _clearLastOperation] ()
#5  0x0038ee3f in -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] ()
#6  0x0051be23 in -[UINavigationTransitionView _notifyDelegateTransitionDidStopWithContext:] ()
#7  0x0051cfd2 in -[UINavigationTransitionView _cleanupTransition] ()
#8  0x00308665 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
#9  0x003084f7 in -[UIViewAnimationState animationDidStop:finished:] ()
#10 0x0200c6cb in run_animation_callbacks ()
#11 0x0200c589 in CA::timer_callback ()
#12 0x01225fe3 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#13 0x01227594 in __CFRunLoopDoTimer ()
#14 0x01183cc9 in __CFRunLoopRun ()
#15 0x01183240 in CFRunLoopRunSpecific ()
#16 0x01183161 in CFRunLoopRunInMode ()
#17 0x01a5a268 in GSEventRunModal ()
#18 0x01a5a32d in GSEventRun ()
#19 0x002e642e in UIApplicationMain ()
#20 0x00001b28 in main (argc=1, argv=0xbffff070) at /Users/nick/Documents/MyApp/main.m:14

EDIT2: метод Dealloc, при котором происходит сбой:

- (void)dealloc
{
    [context release]; // a managed object context -- when table entries are selected, they get cached in core data
    [tableDataArray release];
    [detailViewController release]; // <-- line 290, this is where it crashes
    [super dealloc];
}

person nick    schedule 30.06.2011    source источник


Ответы (4)


Вы либо:

A) Забыли сохранить объект, хранящийся в вашем detailViewController ivar

or

B) Слишком много раз освобождал объект, хранящийся в вашем detailViewController ivar

Таким образом, когда вы пытаетесь освободить detailViewController в своем методе -dealloc, он уже освобожден и указывает на недопустимую память. Вы должны проверить места, где вы установили значение detailViewController в этом классе для одной из этих ситуаций. Если вы его не видите, добавьте код, в котором вы манипулируете этим ivar, к своему вопросу, чтобы мы могли его изучить.

person Ryan    schedule 30.06.2011
comment
Оказалось, что это вариант B — over-released свойство, которое у меня было в контроллере подробного представления. Но вы правы — EXC_BAD_ACCESS всегда попадает в одну из этих двух категорий. - person nick; 01.07.2011
comment
Круто, рад, что смог помочь. Когда у вас будет возможность, отметьте мой ответ как принятый, чтобы другие люди правильно ответили на вопрос. - person Ryan; 01.07.2011

Звучит очень похоже на сбой EXC_BAD_ACCESS, который я недавно получил.

Если я правильно помню, Xcode сообщил, что произошел сбой в этой строке:

int retVal = UIApplicationMain(argc, argv, nil, nil);

и я думаю, что NSZombie сообщил, что сообщение получил CALayer.

Я предполагаю, что ваша ситуация может быть похожей. Вы можете это подтвердить?

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

person Erik B    schedule 30.06.2011
comment
Я ничего не получаю от NSZombie (хотя он включен), но я добавил трассировку стека сбоя, если это поможет. - person nick; 30.06.2011
comment
@nick Сбой в вашем Dealloc. Публикация реализации Dealloc MyTableViewController может помочь разобраться в этом. - person Erik B; 30.06.2011

Ну вот я и разобрался с ошибкой. Когда я сказал в своем исходном сообщении, что я настраиваю и нажимаю контроллер подробного представления, у меня была ошибка управления памятью (чрезмерное освобождение) в одном из свойств, которые я установил в контроллере подробного представления при настройке. контроллер подробного представления. Ошибка проявилась каким-то косвенным образом, но я поймал ее, когда попытался воссоздать ошибку в другой, новой, более простой ВК.

Спасибо тем, кто предложил помощь.

person nick    schedule 01.07.2011

Попробуйте сохранить detailViewController после того, как вы присвоите ему значение. Если это работает, это где-то перевыпущено.

person Valentin Radu    schedule 01.07.2011