2010-01-29 4 views
0

У меня ужаснулась ошибка, которую я просто не могу понять, как отлаживать. В основном я запускаю свой код на симуляторе, и все в порядке.Приложение для iPhone отладки

Однако, когда я иду на фактическое устройство, я получаю ошибку EXC_BAD_ACCESS. К сожалению, при работе на телефоне под отладчиком проклятая вещь работает нормально, поэтому я не могу судить, где происходит ошибка.

У меня была одна трассировка стека, которую я не мог воспроизвести, поэтому я уверен, что строка в моем коде, вызывающая проблему, является этой (но я не могу для жизни меня понять как это может быть):

[[NSNotificationCenter defaultCenter] postNotificationName:@"SubscriberChanged" object: nil]; 

фактическая ошибка была на objc_msgSend около четырех кадров ниже этой линии, но его в коде, который, как представляется, быть частью iPhone SDK, так что я не имею источника в осмотрите его.

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

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


#0 0x30011940 in objc_msgSend() 
#1 0x3054dc80 in _nsnote_callback() 
#2 0x3024ea58 in _CFXNotificationPostNotification() 
#3 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:]() 
#4 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:]() 
#5 0x000027c6 in -[My2CentsAppDelegate handleMOCChange:] (self=0x1159d0, _cmd=0x2bf90, notification=0x147400) at /Users/sdussin/Desktop/UPOD Research LLC/Development/My2Cents/Classes/My2CentsAppDelegate.m:52 
#6 0x3054dc80 in _nsnote_callback() 
#7 0x3024ea58 in _CFXNotificationPostNotification() 
#8 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:]() 

Кадр № 5 в трассировке стека соответствует строке выше.

ответ

2

Если вы не можете повторить сбой в отладчик, вы можете попробовать другие подходы к решению этой проблемы:

  • обзор кода (возможно, попросите друга или сослуживца для обзора кода)
  • Добавить logging и утверждение
  • Активировать все (или, по крайней мере, большинство) предупреждений компилятора и слушаться их
  • Убедитесь, что использовать [] лязг 2 статического анализатора и подчиняться его предупреждение

Специально clang неплохо находит ошибки управления памятью. И EXC_BAD_ACCESS пахнет.

Возможно, был обнаружен один из наблюдателей, зарегистрировавшихся в NSNotificationCenter. Помните, что

Важная: Уведомление центр не сохраняет своих наблюдателей, поэтому, вы должны убедиться, что вы наблюдатели Отмена регистрации (с использованием removeObserver: или removeObserver: имя: объект :) перед тем они освобождаются. (Если вы этого не сделаете, вы будете генерировать ошибку времени выполнения, если центр посылает сообщение освобожденного объекта.)

+0

Оказалось, что уведомление возникло из-за проблемы. У меня, видимо, несколько экземпляров объекта вида в моем NIB. Когда они загрузились, каждый из них зарегистрировался для уведомления, затем только один из них был сохранен. Остальные были освобождены, но не были отменены для уведомления. Спасибо всем ... – Steve

-1

Обычно, когда вы получаете случай, когда что-то работает на тренажере, но не устройство или наоборот, причиной является библиотека/фреймворк, который не скомпилирован для процессора, с которым он врезался.

В вашем случае у вас будет библиотека/структура ARM, которая отлично работает на устройстве, но сбой на симуляторе, работающем на i386.Я бы проверял наследование любого объекта, зарегистрированного для этого уведомления.

2

Вы можете использовать NSZombieEnabled (Google it) для отслеживания такого рода вещей. Кроме этого, я второй oefe: вам, вероятно, нужно отменить регистрацию какого-либо наблюдателя, например. контроллер просмотра, который был выгружен, но все еще зарегистрирован как наблюдатель.

+0

Очень хороший совет - не забудьте положить если (GetEnv ("NSZombieEnabled") || GetEnv ("NSAutoreleaseFreedObjectCheckEnabled")) \t \t NSLog (@ "включен NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled!"); в вашем AppDelegate.m, чтобы предупредить вас, если вы забудете отключить его, когда это не требуется. –

+0

жаль насчет форматирования, никаких кодовых тегов в поле комментариев. –

+0

Один вопрос, который у меня был об этом: если я работаю по телефону и не использую отладчик, как я могу увидеть вывод NSZombieEnabled? У меня создалось впечатление, что зомби записываются на консоль при работе под отладчиком, но куда они идут по телефону? – Steve

1

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

Просмотрите все места в своем коде, на которых вы подписаны, и посмотрите, где вы пропустили отмену подписки (например, вы отменили подписку на dealloc?).

Также как упоминалось нами NSZombieEnabled = YES, флаг среды, который вы установили, щелкнув правой кнопкой мыши на исполняемом файле в браузере проекта XCode и перейдите на вкладку «Аргументы» и добавив его в переменные среды. Затем следите за журналом, когда вы отправляете уведомление, вы видите сообщение с надписью «message blah sent to deallocated instance».

1

Трассировка привязки сообщает вам, что объект, зарегистрированный для уведомлений «SubscriberChanged», был освобожден. Самый простой способ справиться с этой проблемой - искать все классы, которые регистрируются для уведомления «SubscriberChanged» и дезарегистрировать их в своем методе [dealloc].

Смежные вопросы