2014-09-19 46 views
12

從iOS8開始,我的遊戲突然間開始崩潰。有點調試後,我發現,遊戲崩潰在以下兩個地方:iOS 8 SpriteKit在添加或移除子區塊/動作時崩潰

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

而第二位:

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

在iOS 7.1中的碰撞沒有發生的。它只在iOS8上崩潰。 對於第一個崩潰我更換了removeFromParent行動:

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

,這似乎解決了問題。

對於第二次崩潰,我做了同樣的事情(在主線程中添加精靈)並且崩潰消失了。

崩潰日誌:

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 

我的問題是,爲什麼只在iOS8上的崩潰? (在許多的iOS 7.1測試中,它永不死機)

+1

我沒有找到關於根本原因的信息,但我想我會注意到,另一個很好的解決方法是將'removeFromParent'示例放在'runAction'的完成塊中。像:'[node runAction:[SKAction fadeOutWithDuration:1.0] completion:^ {[node removeFromParent]; }];'。 – 2014-10-04 13:33:39

+0

當我在碰撞中移除精靈時,我認爲會發生這種情況(至少在我的遊戲中),然後精靈套件的內部'shouldCullNonVisibleNodes'嘗試移除精靈,但它已經從內存中移除。當我在碰撞時將孩子從父母身邊移走時,我正在經歷這種情況,但隨後碰撞繼續進行。 ' - (void)武器:(武器*)武器didCollideWithMonster:(怪物*)怪物 { if(weapon.parent){0} {weapon removeFromParent]; } }' 在刪除之前檢查精靈是否有父級,修復此問題爲碰撞多次運行。 – 2015-01-25 17:23:56

+0

哦,是的。我還設置了'skView.shouldCullNonVisibleNodes = false;'因爲我的遊戲邏輯處理所有的節點刪除。 – 2015-01-25 17:27:32

回答

3

我在iOS8上面臨着一個問題,羅列在:

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

dispatch_async也有幫助。

並注意所有:崩潰沒有發生immidiatly - 它大約需要0.5秒,代碼後,甚至可以執行。

+0

事實上,崩潰並不是立即執行,因爲SpriteKit runloop運行在不同的線程(可能是主線程)上,所以額外的代碼行可能會在崩潰之前執行,如您所述。 – giorashc 2014-09-19 15:52:07

+1

在這種情況下如何調試和查找崩潰點?誰知道任何方法,除了手動評論的行動?.. :( – djdance 2014-09-19 15:58:53

+0

你們有沒有想到這一點?我遇到了崩潰以及 – 2014-10-16 14:49:00