Что вызывает «EXC_BAD_ACCESS» при вызове селектора? - PullRequest
0 голосов
/ 11 августа 2011

Когда селектор вызывается в Objective-C, и приложение аварийно завершает работу, в результате чего стек отладки указывает на селектор, что является причиной этого?Из того, что я понимаю, это происходит в результате ошибки памяти.Однако и объект, которому я отправляю команду, и параметр (массив) действительны.Я могу сказать, потому что эти два объекта показывают местоположения памяти, а также другую информацию, когда они наведены в Xcode.

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

Кроме того, этот селектор вызывается часто.Он всегда имеет дело с одними и теми же типами объектов, и нет ничего, что бы указывало на ненормальное поведение перед моим сбоем.
Это сбои нечасты, происходят каждые 10 минут или меньше.

Поскольку я начинающий программист, вероятно, что-то не так с кодом внутри селектора.Часто я сравниваю указатели объектов следующим образом:

if (thisObject.pointerToSomeObject == nil) { //do stuff...

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

Дополнительная информация: Я использую cocos2d версии 1.0.0, Xcode 4.1.Тестирование на симуляторе iPad.

Любая помощь приветствуется, даже ссылки на соответствующие статьи по отладке будут полезны.


РЕДАКТИРОВАТЬ

Разработки:

Поток отладки по умолчанию, указывающий на селектор, с ошибкой неверного доступа может означать, что плохой доступ происходит в ходе выполнения этого селектора.Можно включить дальнейшую отладку с помощью NSZombies, чтобы найти точную линию.

Итак, после включения NSZombies проблема раскрывается более подробно.(Спасибо @Lou Franco за этот урок плохого доступа)

Теперь, что может заставить:

if ([thisZombie target] == nil)

оценить НЕТ, но выбрасывать неправильный доступ при доступе к целому числу в [thisZombie target]?target - указатель на объект NSO (зомбированный)

else {

  int diffx = [thisZombie x] - [[thisZombie target] x];
  //                                          ^^ ----- bad access here

** РЕДАКТИРОВАТЬ 2 **

В синтаксисе илиоценка канала:

if (!thisZombie.target && thisZombie.leader && !thisZombie.leader.dead)

thisZombie.leader.dead останавливает поток с помощью: "* - [Zombie dead]: сообщение отправлено освобожденному экземпляру 0x2108f0"

IПредположим, я должен упомянуть, что в этой игре есть «Зомби», которые не следует путать с «NSZombie»

Итак, программа оценивает «thisZombie.target» как «true», но когда я иду, чтобы получить доступ к «thisZombie».target.x "Программа прекращает выполнение.

Почему?


РЕДАКТИРОВАТЬ 3

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

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

Ответы [ 3 ]

1 голос
/ 11 августа 2011

Я написал этот блог, чтобы помочь понять и отладить EXC_BAD_ACCESS

http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

В порядке простоты

  1. Запустить сборку и анализ -- Вы получаете чистую сборку?Посмотрите на то, что он говорит, но вы можете пока игнорировать проблемы утечки - ищите проблемы отправки сообщений освобожденным объектам

  2. Запуск с NSZombiesEnabled - это делает объекты никогда не освобождаемыми, а затемпожаловаться, если сообщение отправлено объекту с retainCount 0. 0. 1014 *

  3. Включите Guard Malloc, а затем используйте специальные команды GDB для проверки целостности кучи.Проблема в том, что вам нужно пройти и сделать это до того, как вы столкнетесь, чтобы найти реальную проблему.Это может произойти сбой где-то еще ближе к вашей проблеме, хотя

РЕДАКТИРОВАТЬ: на основе вашей информации выше.Вы освободили thisZombie.leader, но не установили его на ноль.Возможно, вы забыли, чтобы этот Зомби сохранил его, поэтому его рано освободили.

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

В Objective C на iOS, в чем (стиль) разница между "self.foo" и "foo" при использовании синтезированных геттеров?

0 голосов
/ 12 августа 2011

Вам необходимо проверить, был ли инициализирован ваш массив или какая-либо другая переменная. Использование NSLog или точек останова может помочь вам найти точную переменную, вызывающую эту ошибку. В случае, если какой-то параметр передан или возвращен, то причина, предложенная Максом, также действительна.

Это поможет найти точную проблему, если вы сможете опубликовать код.

0 голосов
/ 11 августа 2011

Даже если объект обнаруживает ячейку памяти, это не значит, что она действительна. Возможно, он освобожден, и вы просто держите указатель на мусор.

...