2014-09-19 4 views
12

A partire da iOS8 il mio gioco ha iniziato a bloccarsi all'improvviso. Dopo un po 'di debugging ho trovato che il gioco si blocca nelle due seguenti luoghi:iOS 8 SpriteKit si arresta in modo anomalo all'aggiunta o alla rimozione di un bambino dal blocco/dall'azione

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

e il secondo posto:

[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]]]]; 

Su iOS 7.1 l'incidente non si verifica. Si blocca solo su iOS8. Per la prima caduta ho sostituito l'azione removeFromParent con:

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

E questo sembra risolvere il problema.

Per il secondo crash ho fatto la stessa cosa (aggiungendo lo sprite nel thread principale) e lo schianto era sparito. log

Crash:

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 

E la mia domanda è: perché si pianta solo su iOS 8? (Su molti iOS 7.1 test non è mai caduto)

+1

Non ho informazioni sulla causa principale, ma ho pensato di notare che un'altra buona soluzione per l'esempio 'removeFromParent' è di inserirla nel blocco di completamento di' runAction'. Come: '[nodo runAction: [SKAction fadeOutWithDuration: 1.0] completamento:^{[nodo removeFromParent]; }]; '. –

+0

Penso che questo accada (almeno nel mio gioco) quando rimuovo una sprite in una collisione, e poi di kit sprite interna 'shouldCullNonVisibleNodes' cerca di rimuovere lo sprite, ma è già stato rimosso dalla memoria. Stavo sperimentando questo quando stavo rimuovendo i bambini dai loro genitori in caso di collisione, ma poi la collisione continuava a funzionare. '- (void) Arma: (Arma *) arma didCollideWithMonster: (mostro *) mostro { se (weapon.parent) { [arma removeFromParent]; } } Controllare se lo sprite ha un genitore prima di rimuoverlo, corretto questo mentre la collisione era in esecuzione più volte. –

+0

Oh sì. Ho anche impostare 'skView.shouldCullNonVisibleNodes = false;' come gestisce la mia logica gioco tutta la rimozione di nodi. –

risposta

3

ho affrontato con un problema in enumerate in iOS 8:

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

dispatch_async ha aiutato troppo.

E nota tutto: crash non occorso immidamente - ci vogliono circa 0,5 secondi, e il codice prima e dopo può anche essere eseguito.

+0

In effetti, l'arresto anomalo non è immediato in quanto il runloop SpriteKit viene eseguito su un thread diverso (probabilmente il thread principale) in modo che righe di codice aggiuntive possano essere eseguite prima di arrestarsi in modo anomalo. – giorashc

+1

Come eseguire il debug e trovare il punto di arresto in questo caso? Chi conosce un metodo tranne il commento manuale delle azioni? .. :( – djdance

+0

avete capito questo? Sto vivendo un incidente pure –

Problemi correlati