Повреждение на EXC_BAD_ACCESS в XCode?

Попробуйте открыть его в шестнадцатеричном редакторе и проанализировать.

45
задан jasonh 25 October 2009 в 22:50
поделиться

5 ответов

Для любых ошибок EXC_BAD_ACCESS вы обычно пытаетесь отправить сообщение выпущенному объекту. ЛУЧШИЙ способ отследить их - использовать NSZombieEnabled .

Это работает, никогда не освобождая объект, а превращая его в «зомби» и установить внутри него флаг, который говорит, что он обычно был бы выпущен. Таким образом, если вы попытаетесь получить к нему доступ снова, он по-прежнему будет знать, что это было до того, как вы сделали ошибку, и с этой небольшой информацией вы обычно можете вернуться назад, чтобы увидеть, в чем была проблема.

Это особенно помогает в фоновом режиме потоков, когда отладчик иногда выскакивает из любой полезной информации.

ОЧЕНЬ ВАЖНО ПРИМЕЧАНИЕ , однако, вам необходимо на 100% убедиться, что это только в вашем отладочном коде, а не в вашем коде распространения. Поскольку ничего никогда не выпускается, ваше приложение будет протекать, просачиваться и протекать. Чтобы напомнить мне об этом, я поместил этот журнал в свой appdelegate:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

Если вам нужна помощь в поиске точной строки, выполните Build-and-Debug ( CMD-Y ) вместо Build- and-Run ( CMD-R ). Когда приложение вылетает,

84
ответ дан 26 November 2019 в 20:55
поделиться

О вашем массиве. Строка

NSMutableArray *array = [NSMutableArray array];

фактически дает вам не сохраненный объект, а скорее объект автозапуска. Вероятно, он будет сохранен в следующей строке, но тогда вам не следует выпускать его в третьей строке. См. this

Это фундаментальное правило:

Вы становитесь владельцем объекта, если создаете его с помощью метода, имя которого начинается с «alloc» или «new» или содержит «copy» (например, alloc, newObject или mutableCopy), или если вы отправляете ему сообщение о сохранении. Вы несете ответственность за отказ от владения объектами, которыми вы владеете, с помощью выпуска или автоматического выпуска. В любой другой раз, когда вы получите объект, вы не должны его освобождать.

17
ответ дан 26 November 2019 в 20:55
поделиться

Xcode / gdb всегда прерывается на EXC_BAD_ACCESS , вам просто нужно продвинуться вверх по стеку вызовов, чтобы найти код, который его запустил.

Обратите внимание, что такого рода ошибки часто возникают с автоматически выпущенными объектами, что означает, что основная причина проблемы не в стеке вызовов, вызвавшем EXC_BAD_ACCESS . Вот тогда полезными становятся NSZombieEnabled и NSAutoreleaseFreedObjectCheckEnabled.

7
ответ дан 26 November 2019 в 20:55
поделиться

Из классов Stanford CS193P: если вы добавите точку останова (вручную, путем редактирования точек останова) для символа objc_exception_throw , вы сможете получить гораздо лучшее представление о том, что пошло не так - позволить вещам перейти к точке, где отладчик останавливается сам по себе, как правило, затемняет вещи и портит трассировку стека. Когда вы останавливаетесь в objc_exception_throw, вы часто можете вспомнить, какой именно доступ / операция вызвали вашу проблему.

2
ответ дан 26 November 2019 в 20:55
поделиться

Другой полезный подход - установка точек останова, которые будут срабатывать сразу после возникновения исключения:

Откройте окно точек останова (Выполнить - Показать - Точки останова) и добавьте две символические точки останова, называемые «objc_exception_throw» и « [Повышение NSException] "

От: http://blog.emmerinc.be/index.php/2009/03/19/break-on-exception-in-xcode/

2
ответ дан 26 November 2019 в 20:55
поделиться