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

КСН 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? (На многой прошивке 7.1 тестов никогда не разбилось)

+1

У меня нет информации о первопричине, но я подумал, что я хотел бы отметить, что еще одно хорошее исправление для вашего примера 'removeFromParent' заключается в том, чтобы поместить его в блок завершения для' runAction'. Например: '[node runAction: [SKAction fadeOutWithDuration: 1.0] завершение:^{[node removeFromParent]; }]; '. –

+0

Я думаю, что это происходит (по крайней мере, в моей игре), когда я удаляю спрайт при столкновении, а затем внутренний 'mustCullNonVisibleNodes' спрайт-набора пытается удалить спрайт, но он уже удален из памяти. Я испытывал это, когда я удалял детей от своих родителей при столкновении, но затем столкновение продолжало бежать. '- (void) оружие: (Оружие *) оружие didCollideWithMonster: (Monster *) монстр { { [оружие removeFromParent]; } } ' Проверка того, что у спрайта есть родительский элемент перед удалением, исправлено это, поскольку столкновение выполнялось несколько раз. –

+0

О да. Я также установил 'skView.shouldCullNonVisibleNodes = false;' поскольку моя игровая логика обрабатывает все удаление узлов. –

ответ

3

я столкнулся с проблемой в Перечислять в iOs8:

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

dispatch_async помог тоже.

Отметьте все: авария не произошла immidiatly - она ​​занимает около 0,5 секунды, а код befro и после того, как может быть даже выполнен.

+0

Действительно, авария не является непосредственной, поскольку runloop SpriteKit работает в другом потоке (возможно, в основном потоке), поэтому перед сбоем, как вы упомянули, могут быть выполнены дополнительные строки кода. – giorashc

+1

Как отладить и найти аварийную точку в этом случае? Кто знает какой-либо метод, кроме ручного комментирования действий? .. :( – djdance

+0

Вы, ребята, это выяснили? Я тоже столкнулся с крахом –

Смежные вопросы