12

As of iOS8 my game started to crash all of a sudden. After a bit of debugging I have found that the game crashes in the two following places :

 [sparkNode runAction:[SKAction sequence:@[
                                           //Some actions and finally...
                                           [SKAction removeFromParent]]]]; // Crashes here (If I remove this action no crash occurs)

And the second place :

[rankTransitionSprite runAction:[SKAction sequence:@[[SKAction scaleTo:1.5 duration:1.0],
                                                     [SKAction runBlock:^{
    CGPoint rankPosition = _rankSprite.position;
    [_rankSprite removeFromParent];
    _rankSprite = [_spritesFactory spriteFromAtlasForImageName:[NSString stringWithFormat:@"rank%d", rank]];
    [self addChild:_rankSprite]; // Crashes here
}],
                                                     [SKAction scaleTo:0.0 duration:1.0],
                                                     [SKAction removeFromParent]]]];

On iOS 7.1 the crash does NOT occur. It only crashes on iOS8. For the first crash I replaced the removeFromParent action with :

[SKAction runBlock:^{
                      dispatch_async(dispatch_get_main_queue(), ^{
                           [sparkNode removeFromParent]; 
                      });
}]

And this seems to solve the issue.

For the second crash I did the same thing (Adding the sprite in the main thread) and the crash was gone.

Crash log:

Thread 0 Crashed:: Dispatch queue: com.apple.spritekit.renderQueue
0   SpriteKit                       0x000000010abed9fe SKCRenderer::preprocessSpriteImp(std::__1::vector<SKCRenderer::SpriteRenderInfo, std::__1::allocator<SKCRenderer::SpriteRenderInfo> >&, SKRenderQuadPool&, SKCSprite const*, _GLKMatrix4 const&, float, unsigned int&, bool) + 372
1   SpriteKit                       0x000000010abee82b SKCRenderer::preprocessSpriteImp(std::__1::vector<SKCRenderer::SpriteRenderInfo, std::__1::allocator<SKCRenderer::SpriteRenderInfo> >&, SKRenderQuadPool&, SKCSprite const*, _GLKMatrix4 const&, float, unsigned int&, bool) + 4001
2   SpriteKit                       0x000000010abee82b SKCRenderer::preprocessSpriteImp(std::__1::vector<SKCRenderer::SpriteRenderInfo, std::__1::allocator<SKCRenderer::SpriteRenderInfo> >&, SKRenderQuadPool&, SKCSprite const*, _GLKMatrix4 const&, float, unsigned int&, bool) + 4001
3   SpriteKit                       0x000000010abe7c21 SKCRenderer::preprocessAndSubmitSpriteInternal(std::__1::vector<SKCRenderer::SpriteRenderInfo const*, std::__1::allocator<SKCRenderer::SpriteRenderInfo const*> >&, std::__1::vector<SKCRenderer::SpriteRenderInfo, std::__1::allocator<SKCRenderer::SpriteRenderInfo> >&, SKRenderQuadPool&, SKCSprite const*, _GLKMatrix4 const&) + 139
4   SpriteKit                       0x000000010abeb7d1 SKCRenderer::submitScene(SKScene*, bool) + 393
5   SpriteKit                       0x000000010abeff16 SKCRenderer::renderScene(SKScene*, bool) + 86
6   SpriteKit                       0x000000010ab87542 -[SKView _renderContent] + 1027
7   libdispatch.dylib               0x000000010c974b94 _dispatch_client_callout + 8
8   libdispatch.dylib               0x000000010c9611e7 _dispatch_barrier_sync_f_invoke + 76
9   SpriteKit                       0x000000010ab870f3 -[SKView renderContent] + 89
10  SpriteKit                       0x000000010ab8415c __29-[SKView setUpRenderCallback]_block_invoke + 54
11  SpriteKit                       0x000000010abb0a54 -[SKDisplayLink _callbackForNextFrame:] + 256
12  QuartzCore                      0x000000010ecf0967 CA::Display::DisplayLinkItem::dispatch() + 37
13  QuartzCore                      0x000000010ecf082f CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 315
14  CoreFoundation                  0x000000010b39e4d4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
15  CoreFoundation                  0x000000010b39e095 __CFRunLoopDoTimer + 1045
16  CoreFoundation                  0x000000010b3613cd __CFRunLoopRun + 1901
17  CoreFoundation                  0x000000010b3609f6 CFRunLoopRunSpecific + 470
18  GraphicsServices                0x000000010d41d9f0 GSEventRunModal + 161
19  UIKit                           0x00000001098cb990 UIApplicationMain + 1282

And my question is why does it crash only on iOS8? (on many iOS 7.1 tests it never crashed)

giorashc
  • 13,691
  • 3
  • 35
  • 71
  • 1
    I've got no information on the root cause, but I thought I'd note that a another good fix for your `removeFromParent` example is to put it in the completion block for `runAction`. Like: `[node runAction:[SKAction fadeOutWithDuration:1.0] completion:^{ [node removeFromParent]; }];`. – Karl Voskuil Oct 04 '14 at 13:33
  • I think this happens (at least in my game) when I remove a sprite on a collision, and then sprite kit's internal `shouldCullNonVisibleNodes` tries to remove the sprite, but it has already been removed from memory. I was experiencing this when I was removing children from their parents on collision, but then the collision kept running. `- (void)weapon:(Weapon *)weapon didCollideWithMonster:(Monster *)monster { if (weapon.parent) { [weapon removeFromParent]; } }` Checking if the sprite has a parent before removing, fixed this as the collision was running multiple times. – Gadget Blaster Jan 25 '15 at 17:23
  • Oh yeah. I have also set `skView.shouldCullNonVisibleNodes = false;` as my game logic handles all removing of nodes. – Gadget Blaster Jan 25 '15 at 17:27
  • What Karl said helped me out. No more crashing on iOS 8 – RyanG Dec 23 '15 at 14:28

1 Answers1

3

I faced with a problem in enumerate in iOs8:

[supers enumerateChildNodesWithName:@"super3" usingBlock:^(SKNode *node, BOOL *stop) {
 ....
            [supers addChild:super3counter]; //crash here
}]; 

dispatch_async helped too.

And note all: crash not occured immidiatly - it takes about 0.5 sec, and code befro and after can be even executed.

djdance
  • 3,110
  • 27
  • 33
  • Indeed, the crash is not immediate as the SpriteKit runloop runs on a different thread (probably the main thread) so extra code lines might be executed before crashing as you mentioned. – giorashc Sep 19 '14 at 15:52
  • 1
    How to debug and find crash point in this case? Who knows any method except manual commenting of actions?.. :( – djdance Sep 19 '14 at 15:58
  • did you guys figure this out? I'm experiencing a crash as well – Steven Ritchie Oct 16 '14 at 14:49
  • 2
    Steven, first do not remove/add right in physics simulator, second - try to find removing/adding in enumerate, 3-rd - in collision function. I havn't face to other cases of crash. You *can* remove/add in update function or via dispatch – djdance Oct 16 '14 at 18:52