2014-09-19 1 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]]]]; 

아이폰 OS 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의에서만 충돌 않습니다입니까?

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

dispatch_async 너무 도움 : 나는 iOS8의에 열거 한 문제에 직면

+1

근본 원인에 대한 정보가 없지만'removeFromParent' 예제의 또 다른 좋은 수정 사항은'runAction'의 완료 블록에 넣는 것입니다. 마찬가지로 :'[node runAction : [SKAction fadeOutWithDuration : 1.0] 완료 :^{[node removeFromParent]; }];'. –

+0

충돌 (적어도 내 게임에서) 충돌에서 스프라이트를 제거한 다음 스프라이트 키트의 내부 'shouldCullNonVisibleNodes'가 스프라이트를 제거하려고 시도하지만 메모리에서 이미 제거되었다고 생각합니다. 나는 부모님이 충돌했을 때 아이들을 제거 할 때 이것을 경험하고 있었지만 충돌은 계속 발생했습니다. 무기가 : (무기 *) 무기 didCollideWithMonster : (몬스터 *) 괴물 { if (weapon.parent) { [weapon removeFromParent]; } } 제거하기 전에 스프라이트에 부모가 있는지 확인하고, 충돌이 여러 번 실행 중일 때이를 수정했습니다. –

+0

오 예. 또한 게임 로직이 모든 노드 제거를 처리 할 때'skView.shouldCullNonVisibleNodes = false; '를 설정했습니다. –

답변

3

(많은 아이폰 OS 7.1 테스트에 추락하지 않음).

모두주의 : 충돌은 거의 발생하지 않습니다. 약 0.5 초가 걸리며 코드 비프 로프와 애프터 콜도 실행될 수 있습니다.

+0

SpriteKit runloop이 다른 스레드 (아마도 주 스레드)에서 실행되므로 실제로 충돌이 발생하지 않습니다. 따라서 언급 한 것처럼 충돌하기 전에 추가 코드 행이 실행될 수 있습니다. – giorashc

+1

이 경우 디버그하고 충돌 지점을 찾는 방법은 무엇입니까? 수동으로 작업을 주석으로 처리하는 것을 제외하고 어떤 방법을 알고 있습니까? ... :(: – djdance

+0

당신도 이걸 알아 냈습니까? 또한 충돌이 발생했습니다 –

관련 문제