Подтвердить что ты не робот

Как отлаживать "сообщение, отправленное на освобожденный экземпляр" в Xcode4?

Я нажал ALT + CMD + R и активировал NSZombieEnabled в Аргументы > Переменные среды. Кроме того, я активировал его в разделе "Диагностика" > "Управление памятью" > "Включить объекты зомби".

Однако, когда я создавал и запускал, в какой-то момент мое приложение аварийно выдавало мне это бесполезное сообщение в консоли:

*** -[CALayer retainCount]: message sent to deallocated instance 0x656b260

Трассировка стека столь же бесполезна. Я переместил ползунок уровня детализации до упора вправо. Тема 1 просто показывает мне это:

screenshot

Все принадлежит системе и нет ни одной строки, связанной с моим приложением. Таким образом, очевидно, NSZombiesEnabled не работает так, как в Xcode 3, где он остановился на мертвом объекте.

Есть ли способ выяснить, какой CALayer освобожден слишком рано?

Обновление: поэтому после создания и запуска еще 100 раз внезапно проблема DISAPPEARED! Он полностью ушел! И лучшая часть: я никак не изменял свой код! В промежутке я несколько раз очищал папку сборки и проецировал чистые команды и несколько раз удалял приложение в Симуляторе.

Обновление 2: К счастью, проблема снова появилась. И теперь это кажется настойчивым. К счастью, потому что я предпочитаю находить первопричину, а не раздражать пользователей случайным образом.

Обновление 3: Наконец-то это произошло случайно:

startButton = newBttn;

должен был быть:

self.startButton = newBttn;

startButton был сохраняющим свойством, а в -dealloc я его выпустил. Таким образом, он был переименован и в большинстве (но не во всех) случаях после того, как взгляд исчез, он разбился, давая это странное сообщение CALayer keepCount.

Инструмент Зомби (CMD + I), наконец, указал, что это связано с кнопкой. Просто не знал, почему и где.

Статический анализатор Clang не жаловался на этот очевидный сбой.

4b9b3361

Ответ 1

Если это снова появится, вы можете запустить специальный инструмент Zombies. Hit Command + I, чтобы профилировать приложение и выбрать инструмент Zombies (вы должны работать на симуляторе). Если вы получаете зомби, вы можете отобразить всю историю памяти (каждый сохранить/освободить) для этого объекта, что очень полезно при отслеживании ошибок.

Ответ 2

В дополнение к Джеффу большой ответ; сделать практически то же самое, но без необходимости открывать инструменты или профиль вашего приложения, вы можете установить NSZombieEnabled, MallocStackLogging и guard malloc в отладчике. Затем, когда ваше приложение выйдет из строя, введите его в консоли gdb:

(gdb) info malloc-history 0x543216

Замените 0x543216 адресом объекта, который вызвал сбой, и вы получите гораздо более полезную трассировку стека, и это поможет вам точно определить точную строку в коде, вызывающую проблему.

В этой статье есть дополнительная информация.