Привет! В этой статье я постараюсь рассказать о том, как можно облегчить себе жизнь при отладке приложений для iPhone и Mac. Мы поговорим об отладке исключения EXC_BAD_ACCESS, одного из самых неприятных исключений в природе.
Исключение EXC_BAD_ACCESS происходит, когда мы пытаемся отправить сообщение уже выпущенному объекту.
Ситуация обычно осложняется тем, что к моменту возникновения ошибки в стеке вызовов уже нет информации, которая могла бы нам помочь.
То есть непонятно, какой конкретно объект был освобожден.
И, более того, непонятно, в каком месте кода оно освободилось :).
Будет еще веселее, если приложение будет многопоточным.
К счастью, ребята из Яблоко приложил все усилия, чтобы помочь нам.
Они создали класс-заглушку НС Зомби .
Если включить его поддержку (как это сделать я расскажу ниже), то после удаления каждого объекта «зомби» будет жить на своем месте (т.е.
по своему адресу в памяти) и получать сообщения, что позволит вы сможете во время отладки определить, какой объект был освобожден, и исправить ошибку.
Итак, начнем.
В один прекрасный день ваше приложение для iPhone или Mac начинает давать сбой, и в консоли отладчика вы видите следующее сообщение: Программа получила сигнал: «EXC_BAD_ACCESS».
И, по сути, не более того.
Стек вызовов вам, скорее всего, тоже не помог.
В окне Группы и файлы (оставил в xCode ) найди ветку Исполняемые файлы .
Щелкните правой кнопкой мыши исполняемый файл вашего приложения и выберите Получить данные .
В появившемся окне откройте вкладку Аргументы и добавьте две переменные среды: НСЗомбиВключено И MallocStackLoggingNoCompact .
Установить НСЗомбиВключено значение ДА , А MallocStackLoggingNoCompact — 1 .
Как это должно выглядеть показано на скриншоте:
Теперь запустите приложение и повторите шаги, необходимые для воспроизведения ошибки.
В консоли отладчика вместо сообщения о EXC_BAD_ACCESS вы должны увидеть что-то вроде этого: 2010-01-25 14:35:24.840 MyApplication[1393:20b] *** -[CFString retain]: message sent to deallocated instance 0x42a5060
Это означает, что когда-то у вас был объект класса CFString по адресу 0x42a5060 .
Его уже выпустили, но ваша программа не останавливается и пытается отправить ему сообщение удерживать .
Остается только найти этот объект и найти место в коде, где вызывался лишний выпускать .
Или не позвонили удерживать , зависит от конкретной ситуации :)
Вам поможет следующее: в консоли отладчика введите следующую команду: shell malloc_history 1393 0x42a5060
Вместо 1393 вам следует ввести идентификатор процесса (PID).
Вы можете увидеть это в сообщении об ошибке консоли сразу после имени приложения.
И вместо 0x42a5060 введите адрес освободившегося объекта (его также можно увидеть в сообщении об ошибке).
В результате ваши глаза увидят такую ужасную картину:
Не пугайтесь, все не так страшно, как может показаться на первый взгляд. Внизу найдите имена классов и методов, присутствующих в вашем коде.
То есть написанное вами.
Где-то таится злосчастный вызов выпускать .
Найдите и исправьте.
P.S. Краем глаза я где-то прочитал, что такие ошибки можно отловить с помощью Instruments/ObjectAlloc. Я был бы очень признателен, если бы мне кто-нибудь дал водочки.
Да, совет Теги: #iphone #debug #debugging #mac os x #mac os x #objective-c #xcode #разработка для iOS
-
Введение В Хранилище Данных
19 Oct, 24 -
Полезные Материалы По San
19 Oct, 24 -
Глупость В Этой Индустрии* Невероятна.
19 Oct, 24 -
Одна Идея Для Монетизации Социальных Сетей
19 Oct, 24