Поток 1: EXEC_BAD_ACCESS (код =1), адрес =0x6000000000000018)

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

Проблема: ошибка появляется практически случайно. Это может появиться после того, как первый враг убит или N-й враг убит. Тем не менее, он появляется только тогда, когда враг убит.

Тестирование: запуск iOS 8 beta 5, Xcode 6 beta 5 на iPhone 5s.

Поток кода:

Экземпляры класса Enemy SKNodes создаются в начале уровня и сохраняются в NSMutableArray для справки:

Goblin *newGoblin = [[Goblin alloc] initFacingDirection:1];
// set various properties…
[enemyGoblins addObject:newGoblin];

Меч игрока вступает в контакт с врагом:

NSMutableArray *discardedItems = [NSMutableArray array];

for(Goblin *object in enemyGoblins)
{
    [object runBloodBurst:true damagePoints:_player.swordDamage];
    if(object.goblinHealth < 0)
        [discardedItems addObject:object];
}

if([discardedItems count] > 0)
    [enemyGoblins removeObjectsInArray:discardedItems];

В классе гоблинов код "die":

if(self.goblinHealth < 0)
{
    SKAction *wait0 = [SKAction waitForDuration:1.0];

    SKAction *block0 = [SKAction runBlock:^{
        [self removeActionForKey:@"animation"];
        [self runAction:[_animations goblin_dieLeft]];
    }];

    SKAction *block1 = [SKAction runBlock:^{
        [self removeFromParent];
    }];

    [self runAction:[SKAction sequence:@[block0, wait0, block1]]];

}

Что я пробовал: я отключил код discardedItems, потому что думал, что ARC может сбросить объект из памяти после потери ссылки, а последующий класс "Goblin" "die animation" вызовет сбой, но это не решит проблему. Я пробовал зомби и контрольные точки, но также не получил никаких полезных подсказок.

Я лаю не на том дереве в отношении того, что я пробовал, или кто-то сталкивался с подобной проблемой в бета-версии 5?

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

Вот обратный след:

(lldb) bt * thread # 1: tid = 0x3264b, 0x000000018cb13434 SpriteKitSKCSprite::update(double) + 404, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x7000000000000018) frame #0: 0x000000018cb13434 SpriteKitSKCSprite:: update (double) + 404 кадр №1: 0x000000018cb13440 SpriteKitSKCSprite::update(double) + 416 frame #2: 0x000000018cb13440 SpriteKitSKCSprite:: update (double) + 416 кадр # 3: 0x000000018cacbf28 SpriteKit-[SKScene _update:] + 140 frame #4: 0x000000018cae63f8 SpriteKit- [SKView (Private) _update:] + 568 кадр # 5: 0x000000018cae3a10 SpriteKit-[SKView renderCallback:] + 764 frame #6: 0x000000018cae0a9c SpriteKit__29- [SKView setUpRenderCallback] _block_invoke + 60 кадров # 7: 0x000000018cb0d890 SpriteKit-[SKDisplayLink _callbackForNextFrame:] + 272 frame #8: 0x000000010042ca9c libglInterpose.dylib- [DYDisplayLinkInterposer forwardDisplayLinkCallback:] + 168 кадров № 9: 0x000000018c615b90 QuartzCoreCA::Display::DisplayLinkItem::dispatch() + 32 frame #10: 0x000000018c615a28 QuartzCoreCA:: Display:: DisplayLink:: dispatch_items (длинная без знака, длинная без знака, длинная без знака) + 324 кадра # 11: 0x00000001897dddc0 IOKitIODispatchCalloutFromCFMessage + 376 frame #12: 0x00000001885dcf34 CoreFoundation__CFMachPortPerform + 180 frame # 13: 0x00000001885f1b38 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 frame #14: 0x00000001885f1a98 CoreFoundation__CFRunLoopDoSource1 + 436 кадр № 15: 0x00000001885efa18 CoreFoundation__CFRunLoopRun + 1640 frame #16: 0x000000018851d664 CoreFoundationCFRunLoopRunSpecific + 396 кадра # 17: 0x000000019154f5a4 GraphicsServicesGSEventRunModal + 168 frame #18: 0x000000018ccd6164 UIKitUIApplicationMain + 1488 * frame # 19: 0x0000000100165530 CarcerQuestmain(argc=1, argv=0x000000016fdab9d8) + 116 at main.m:16 frame #20: 0x000000019885aa08 libdyld.dylibначало + 4 (лдб)

3 ответа

Менять

[self runAction:[SKAction sequence:@[block0, wait0, block1]]];

в

[self runAction:[SKAction sequence:@[block0, wait0]] completion:^{ [_self removeFromParent]; }];

Я столкнулся с той же проблемой при обновлении кода IOS7 для запуска на IOS8, и с помощью блока завершения исправил проблему.

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

Вы можете увидеть мой код изменения здесь: https://github.com/ik/2048/commit/3ffec547367320c7e179624a14ac5867ed1acea2

В основном, что происходит, runAction асинхронный Это выполняется в следующем цикле обновления экрана (отсюда вызов ссылки на отображение в вашей трассировке стека). Так что если вы позвоните removeSomething после вашего runAction, это может быть выполнено до того, как действие будет выполнено, и вы потерпите крах.

По крайней мере, это то, что поймало меня - я не знаю, почему это никогда не происходило в iOS 7. См. Код ниже.

- [self removeFromParentCell]; // Used to call it here - wrong.
  SKAction *wait = [SKAction waitForDuration:GSTATE.animationDuration];
  SKAction *remove = [SKAction removeFromParent];
- [self runAction:[SKAction sequence:@[wait, remove]]];
+ [self runAction:[SKAction sequence:@[wait, remove]] completion:^{
+   [self removeFromParentCell];  // This is right.
+ }];

Поискив форумы поддержки Apple и запустив тот же проект на iOS 7, выясняется, что это ошибка бета-версии, а не неисправный код.

Другие вопросы по тегам