Sprite Kit 中的 SKSpinLockSync 是什么以及如何修复它 [英] What is SKSpinLockSync in Sprite Kit and how do I fix it

查看:17
本文介绍了Sprite Kit 中的 SKSpinLockSync 是什么以及如何修复它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到了包含以下堆栈跟踪的错误报告,但我不知道问题出在哪里.我已经看到一些建议,这可能是由于在纹理图集中使用了发射器的图像,或者在添加发射器时在同一运行循环中移除了发射器,但我认为这两种情况都不会发生.这是一个零星的问题,我无法重新创建它.我只在错误报告中看到它.我很乐意提供任何帮助.

I am receiving a bug report with the following stack trace and I have no idea what the problem is. I've seen suggestions that this could be caused by having an emitter's image in a texture atlas or by removing an emitter in the same run loop as it is added but I don't think either of these is happening. It's a sporadic issue and I can't recreate it. I only see it in bug reports. I would love any help.

0    libsystem_platform.dylib    OSSpinLockLock + 1
1    SpriteKit   SKSpinLockSync(int*, void ()() block_pointer) + 92
2    SpriteKit   -[SKTexture loadImageData] + 300
3    SpriteKit   -[SKTexture size] + 42
4    SpriteKit   SKCEmitterSprite::update(double) + 3136
5    SpriteKit   SKCSprite::update(double) + 354
6    SpriteKit   SKCSprite::update(double) + 354
7    SpriteKit   -[SKScene _update:] + 174
8    SpriteKit   -[SKView(Private) _update:] + 324
9    SpriteKit   -[SKView renderCallback:] + 820
10   SpriteKit   __29-[SKView setUpRenderCallback]_block_invoke + 130
11   SpriteKit   -[SKDisplayLink _callbackForNextFrame:] + 254
12   QuartzCore  CA::Display::DisplayLinkItem::dispatch() + 98
13   QuartzCore  CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 344
14   IOMobileFramebuffer     IOMobileFramebufferVsyncNotifyFunc + 104
15   IOKit   IODispatchCalloutFromCFMessage + 248
16 ...   CoreFoundation  __CFMachPortPerform + 136
17   CoreFoundation  __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 34
18   CoreFoundation  __CFRunLoopDoSource1 + 346
19   CoreFoundation  __CFRunLoopRun + 1406
20   CoreFoundation  CFRunLoopRunSpecific + 524
21   CoreFoundation  CFRunLoopRunInMode + 106
22   GraphicsServices    GSEventRunModal + 138
23   UIKit   UIApplicationMain + 1136
24   myApplication  main.m line 16  main

我现在意识到我在几种不同的情况下遇到了 SKSpinLockSync 问题,而发射器并不总是如此.我认为我经常在发射器上看到它的唯一原因是因为这是应用程序中图像加载的最大份额,所以它只是统计上最有可能的.堆栈跟踪的前四行始终相同.因此,直到并包括 [SKTexture Size].

I'm now realizing that I get the SKSpinLockSync problem in a few different situations and not always with the emitters. I think that the only reason that I see it so often with the emitter is because that is the lions share of the image loading in the app so it's just the statistically most likely. The top four lines of the stack trace are always the same. So, up to and including [SKTexture Size].

推荐答案

我遇到了同样的问题,我打电话的时候发现了

I had the same problem and I found that when I call

NSString *p = [[NSBundle mainBundle] pathForResource:name ofType:@"sks"];  
SKEmitterNode *e = [NSKeyedUnarchiver unarchiveObjectWithFile:p];  

很多时候,它会随机使应用程序崩溃并具有相同的崩溃日志

many times, it will randomly crash the app with the same crash log

SKSpinLockSync(int*, void ()() block_pointer) + 36  
-[SKTexture loadImageData] + 252  
-[SKTexture size] + 44  
SKCEmitterSprite::update(double) + 2928  

我认为这是 Sprite Kit 的问题,希望苹果能尽快解决这个问题

I think this is Sprite Kit problem and hope Apple will fix this soon

我的解决方案是:不要每次都调用 unarchiveObjectWithFile

unarchiveObjectWithFile 可能与 IO 有关,如果您像游戏中的每一帧一样经常这样做,这可能会崩溃,或者问题来自 SKTexture 缓存系统在需要纹理数据并在非线程安全中调用 loadImageData 时出现问题.

unarchiveObjectWithFile may relate to IO and this may crash if you do that too often like every frame in your game, or the problem come from SKTexture cache system has problem when it need texture data and call loadImageData in non-thread safe.

所以我用副本重用 SKEmitterNode,这是我的功能

So I reuse SKEmitterNode with copy, here is my function

// Emitter Pool
- (SKEmitterNode*)getEmitter:(NSString*)name {
    if(!mDictEmitter)
        self.mDictEmitter = [NSMutableDictionary new];
    SKEmitterNode *e = [mDictEmitter objectForKey:name];
    if(!e){
        NSString *p = [[NSBundle mainBundle] pathForResource:name ofType:@"sks"];
        e = [NSKeyedUnarchiver unarchiveObjectWithFile:p];
        [mDictEmitter setObject:e forKey:name];
    }
    return [e copy];
}

这篇关于Sprite Kit 中的 SKSpinLockSync 是什么以及如何修复它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆