2

SpriteKit game crashes with EXC_BAD_ACCESS after upgrading to iOS8. Happens at random time, for no apparent reason, after playing a while. Exception breakpoint, as well as enabling NSZombie detection in Allocations/Instruments doesn't give any information, so I can't detect the line in my code that causes the error.

Here is the backtrace:

* thread #1: tid = 0x5d267, 0x2fd7c760 SpriteKit`SKCSprite::update(double) + 328, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xc)
frame #0: 0x2fd7c760 SpriteKit`SKCSprite::update(double) + 328
frame #1: 0x2fd2cec8 SpriteKit`-[SKScene _update:] + 200
frame #2: 0x2fd4a8ae SpriteKit`-[SKView(Private) _update:] + 686
frame #3: 0x2fd47a44 SpriteKit`-[SKView renderCallback:] + 748
frame #4: 0x2fd4485c SpriteKit`__29-[SKView setUpRenderCallback]_block_invoke + 116
frame #5: 0x2fd75fcc SpriteKit`-[SKDisplayLink _callbackForNextFrame:] + 248
frame #6: 0x2f91ad7a QuartzCore`CA::Display::DisplayLinkItem::dispatch() + 98
frame #7: 0x2f91abe2 QuartzCore`CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 366
frame #8: 0x341ca82e IOMobileFramebuffer`IOMobileFramebufferVsyncNotifyFunc + 90
frame #9: 0x2d94a51c IOKit`IODispatchCalloutFromCFMessage + 256
frame #10: 0x2c9dcbe4 CoreFoundation`__CFMachPortPerform + 132
frame #11: 0x2c9ed022 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 34
frame #12: 0x2c9ecfbe CoreFoundation`__CFRunLoopDoSource1 + 346
frame #13: 0x2c9eb5e0 CoreFoundation`__CFRunLoopRun + 1608
frame #14: 0x2c938db0 CoreFoundation`CFRunLoopRunSpecific + 476
frame #15: 0x2c938bc2 CoreFoundation`CFRunLoopRunInMode + 106
frame #16: 0x33cc4050 GraphicsServices`GSEventRunModal + 136
frame #17: 0x2ff04a30 UIKit`UIApplicationMain + 1440
* frame #18: 0x001073cc p01g01`main(argc=1, argv=0x00456bd4) + 116 at main.m:16

Apparently, the issue is somehow linked to SpriteKit.

On iOS7, though, game works without any problems.

Is there any other method to locate and eliminate the problem?

kamneed
  • 41
  • 1
  • 5
  • Downvoting? Then take the trouble to explain your action. Thank you. – kamneed Sep 30 '14 at 12:26
  • Now this is a blind shot with the provided information. But there are cases in iOS8 where updating the UI within a block causes an issue, so I suggest you to look there for nodes being added or removed. But again it's a blind shot, does it happen in any specific place or just when the scene is loaded? – gzafra Sep 30 '14 at 21:42
  • @Willhem thanks for the answer, unfortunately I can't provide any piece of code now as Xcode doesn't tell where the issue happens. And there is huge amount of code. It occurs in 10-20 secs after starting of intensive play, no specific event to stick to. I'll try to dig it the block direction. – kamneed Oct 01 '14 at 04:23
  • I have the same problem (and it's similarly hard to trace). On a whim I tried [a workaround suggested by someone having a similar problem with iOS7.1 upgrade](http://stackoverflow.com/a/23570896/1332415). The workaround is to remove all children from a node before removing it from its parent. To my surprise, it worked for me. – Karl Voskuil Oct 03 '14 at 15:21
  • @KarlVoskuil thanks, I'll definitely try your suggestion – kamneed Oct 03 '14 at 15:56
  • @kamneed, on second thought, you might be ahead of me. I'm now at the stage where the elimination of `[SKAction removeFromParent]` is fixing all my crashes. I'm hoping that your answer **is** the correct workaround (for a bug in SpriteKit iOS8, presumably), and that your linked problem with `getAccumulatedBounds()` is, indeed, a different problem. I guess I should give it several hours before I say for sure my problems are gone :) – Karl Voskuil Oct 04 '14 at 01:34

2 Answers2

1

So, apparently the problem was in removeFromParent.

After changing:

SKAction *remove = [SKAction removeFromParent];
[self runAction:[SKAction sequence:@[wait, remove]]];

to:

[self runAction:wait completion:^{
    [self removeFromParent];
}];

the error has gone, but another one appeared:

SpriteKit`SKCShapeSprite::getAccumulatedBounds()

Please head to SpriteKit: EXC_BAD_ACCESS SpriteKit`SKCShapeSprite::getAccumulatedBounds() crash for details.

UPDATE: It turned out that I got ahead of myself: error popped up again after several hours. Now I have two kinds of unsolvable issues, and thinking of rewriting the game from the ground up specifically for iOS8.

Community
  • 1
  • 1
kamneed
  • 41
  • 1
  • 5
  • run your action with a key and remove the key and node when you block is completed (i am just guessing) or set node to nil may be help you out – dragoneye Oct 02 '14 at 09:48
0

Try this by setting a unique name for the name property. Somehow worked for me.

static NSInteger count = 0;

@interface Power ()

- (instancetype)init
{
    if (self = [super init]) {
        count++;
        self.name = @(count).stringValue;
    } return self
}

@end

Notice the objects were deallocating more than once. Maybe because wasn't able to distinguish one object to another of the same type.

Nate Hat
  • 408
  • 4
  • 11