EXC_BAD_ACCESS при простом приведении указателя в Obj-C - PullRequest
2 голосов
/ 15 мая 2010

Частый посетитель, но первое сообщение здесь, на StackOverflow, я надеюсь, что вы, ребята, могли бы помочь мне с этим. Я довольно новичок в Obj-C и XCode, и я столкнулся с этой действительно ... странной ... проблемой. Поиск в Google ничего не дал. По сути, я получаю сигнал EXC_BAD_ACCESS в строке, которая не выполняет разыменование или что-либо подобное, что я вижу. Хотите знать, если вы, ребята, есть идеи, где искать это. Я нашел обходной путь, но понятия не имею , почему это работает ... Строка, на которой прервана ломаная версия, это строка:

LevelEntity *le = entity;

где я получаю плохой сигнал доступа.

Вот так:

ЭТА ВЕРСИЯ РАБОТАЕТ

  NSArray *contacts = [self.body getContacts];
  for (PhysicsContact *contact in contacts)
  {
   PhysicsBody *otherBody;
   if (contact.bodyA == self.body)
   {
    otherBody = contact.bodyB;
   }
   if (contact.bodyB == self.body)
   {
    otherBody = contact.bodyA;
   }

   id entity = [otherBody userData];
   if (entity != nil)
   {
    LevelEntity *le = entity;

    CGPoint point = [contact contactPointOnBody:otherBody];
   }
  }

ЭТА ВЕРСИЯ НЕ РАБОТАЕТ

  NSArray *contacts = [self.body getContacts];
  for (NSUInteger i = 0; i < [contacts count]; i++)
  {
   PhysicsContact *contact = [contacts objectAtIndex:i];
   PhysicsBody *otherBody;
   if (contact.bodyA == self.body)
   {
    otherBody = contact.bodyB;
   }
   if (contact.bodyB == self.body)
   {
    otherBody = contact.bodyA;
   }

   id entity = [otherBody userData];
   if (entity != nil)
   {
    LevelEntity *le = entity;

    CGPoint point = [contact contactPointOnBody:otherBody];
   }
  }

Здесь разница между этими двумя примерами only заключается в том, как я перечисляю свой массив. В первой версии (которая работает) я использую для (... в ...), где, как во второй я использую для (...; ...; ...). Насколько я вижу, они должны быть одинаковыми.

Это серьезно изводит меня. У кого-нибудь есть подобный опыт или идея, что здесь происходит? Было бы действительно здорово :) 1028 *

Ура, Alex

Ответы [ 2 ]

3 голосов
/ 15 мая 2010

Во-первых, если у вас есть сбой, у вас есть обратный след. Всегда предоставляйте обратный след с вашим вопросом (он будет в отладчике и может быть скопирован / вставлен).

Как и предполагал Вохито, наиболее распространенная причина таких сбоев связана с чрезмерным выпуском объектов.

В вашем случае for(;;) и for(... in ...) на самом деле не совпадают. Последнее очень вероятно приводит к тому, что объекты в массиве сохраняются в течение итерации или автоматически высвобождаются при извлечении (я говорю «очень вероятно», потому что я не проверял это - но это объясняло бы поведение).

В своем коде вы изменяете свой объектный граф во время итерации с помощью операторов типа otherBody = contact.bodyB. Если какое-либо из этих утверждений приводит к тому, что один из элементов массива, который повторяется, будет выпущен из-под массива, вы увидите сбой. Точно так же, если модификация графа объекта приводит к тому, что либо contact.bodyA, либо contact.bodyB становится висячей ссылкой, вы увидите сбой.

Все просто догадки. Запишите обратный след и, как предложил Вохито, запустите инструмент «Распределение» в разделе «Инструменты с включенным обнаружением зомби».

1 голос
/ 15 мая 2010

Переменные стека, включая ссылки на объекты, не будут автоматически инициализироваться в nil / 0 / NULL. Попробуйте установить otherBody в ноль в инициализаторе:

PhysicsBody *otherBody = nil;

Если отладчик говорит, что в присваивании le происходит исключение, это может быть оператор над ним, т. Е. [otherBody userData]. Без инициализации otherBody является значением мусора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...