Выследить EXC_BAD_ACCESS без NSZombie?

Я потратил на это два дня и до сих пор не могу найти причину аварии.

Я знаю, что это как-то связано с попыткой доступа к объекту, который был освобожден, но я не знаю, какой доступ или какой объект.

Всякий раз, когда я пытаюсь найти источник EXC_BAD_ACCESS в Google, люди предлагают использовать NSZombies. Проблема в том, что когда я включаю зомби (либо в xcode через переменную окружения, либо в инструменты через свойства ObjectAlloc), программа не падает, как обычно, и зомби ничего не сообщают (ничего не отображается в журналах и ничего не помечено в инструменты). Есть ли что-то, чего мне не хватает в NSZombie?

Я пытался использовать некоторую информацию из отладчика xcode и из ObjectAlloc в инструментах, но вся информация очень загадочная и не очень мне помогает.

Я установил отладчик, чтобы он остановился на исключениях target-c. Когда он это делает, это показывает стек вызовов:

0 objc_msgSend
1 ??
2 -[UITableViewCell removeFromSuperView]
3 -[UIView dealloc]
... etc ...

Прежде всего, что за сделка с "1??"? Что означают знаки вопроса? Во-вторых, как я могу узнать, где это было вызвано в моем коде? Все указанные операции являются слишком общими (например, UIView Deloc, но какой UIView? И где?).

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

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

Я попытался разбросать некоторые NSLogs и точки останова вокруг, но это мне не сильно помогает, потому что сбой происходит после того, как я вытаскиваю контроллер представления из контроллера навигации. Везде, где я ставлю точки останова, точки останова достигаются нормально (я не могу найти точку, чтобы сломаться после аварии). Исключение возникает только тогда, когда я "продолжаю" в отладчике. Как будто сбой происходит за пределами моего кода, поэтому я понятия не имею, где его найти.

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

Если у кого-то есть идеи, как найти такие ошибки без NSZombie, пожалуйста, поделитесь.

Благодарю.

1 ответ

Решение

Ну, я нашел проблему. У меня был собственный класс ячеек таблицы, в котором я сначала вызвал [super dealloc] в методе dealloc (а не в прошлом). Я думаю, что я написал этот класс в спешке и не думал об этом. Я предполагаю, что что-то было выпущено в родителе, что ребенок должен был выпустить?

Таким образом, у меня нет реального ответа на мой собственный вопрос, но в основном я нашел проблему, используя комбинацию специальной трассировки кода и различных методов отладки (точки останова, NSLogs, попытка расшифровать криптографическую трассировку стека и т. Д.).

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

Я надеюсь, что это может помочь кому-то. Я оставлю этот вопрос без ответа на некоторое время, если у кого-то есть более тщательная стратегия отладки, не полагаясь на NSZombies. Также, если кто-то может уточнить, что означают эти два знака вопроса в трассировке стека, это будет полезно.

Другие вопросы по тегам