什么是Sprite Kit中的SKSpinLockSync以及如何解决它

我收到一个带有以下堆栈跟踪的错误报告,我不知道问题是什么。 我已经看到这样的建议,这可能是由于在纹理图集中有一个发射器的图像,或者是在添加的同一个运行循环中移除了一个发射器,但我认为这些都不会发生。 这是一个零星的问题,我无法再创造它。 我只在bug报告中看到它。 我很乐意帮忙。

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]

我有同样的问题,当我打电话时,我发现了

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

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

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

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

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

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

所以我重复使用SKEmitterNode,这是我的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]; } 

OSSpinLock是一种确保multithreading应用程序中的primefaces操作的机制。

我不认为这里存在multithreading问题,而是loadImageData可能提供了在工作的primefaces部分崩溃的数据。 这可能是由于包中缺少(或损坏或不支持的文件格式)纹理。 它肯定是一个导致纹理加载失败的发射器。

尝试在发布配置中测试您的应用程序(编辑方案)一段时间。 一些错误仅在启用了优化的版本构建中浮出水面。 您还可以构建应用程序的特殊版本并将其部署到您的设备并进行测试。 您现在的第一个目标应该是在您自己的设备上validation问题,否则可能很难确定。

调用堆栈确实给你一些提示:问题在于一个sprite的子节点,它是另一个sprite的子节点,它是场景的子节点。 也许这会缩小它。

在类似的情况下我遇到了同样的崩溃,并且能够解决它

就我而言,我试图通过SKAction播放图像序列:

 [SKAction animateWithTextures: timePerFrame:] 

我不确定原因是什么,但我的预感是它与纹理没有被预加载有关。 该方法的文档没有提供任何关于它们是否必须预加载的见解,因此它纯粹是猜想,但从我收集的内容SpriteKit似乎是窒息,因为它无法快速加载图像以显示它们。

在任何情况下,使用[SKTexture preloadTextures:...完全解决了我的崩溃

希望它也能帮助你和其他人!

我在使用SpriteKit制作游戏时遇到了类似的问题。 所有能够从互联网搜索获得的post都无法解决。 有时,如果操作包含multithreading的概念,则特殊操作类型将导致此问题,而不是由于包中的损坏或缺少纹理。 我确实解决了! 换句话说,间接你的代码可能有一种multithreading,即使看起来没有明显的multithreading。

我在Sprite Kit中遇到了这个问题(同样的崩溃日志堆栈)。 我在很多时间内尝试了很多东西 – 最后想出来了,排序:似乎是因为源纹理位于Texture Atlas文件夹中,而且它没有相应的@ 2x图像。 尝试将纹理移出纹理图集和/或添加图像的@ 2x版本。

如果使用SKEmitterNode并同时创建多个(大约在同一时间关闭),我的游戏仍然崩溃。 我不得不手动预加载(创建并添加发射器到场景),然后我能够防止崩溃我必须让粒子效果被创建并添加到场景中并让它运行它的动作。 然后我将粒子alpha设置为0,以隐藏它。 到那时我被失望了,我预装了一切。

使用上面的SKEmitterNodegetEmitter方法,当我在同一时间创建多个1个发射器时,我仍然会崩溃。 我通过在开始时创建一个粒子,将其添加到场景中,并将其alpha设置为0来解决这个问题。这是一种非常好的方式并且它会爆炸,但它可以工作并且不会崩溃。

例:

 @implementation MyGameScene - (instancetype)initWithSize:(CGSize)size { if(self = [super initWithSize:size]){ HitEmitter *emitter = [HitEmitter particle]; // class method use getEmitter method [self addChild:emitter]; [emitter setName:@"temp"]; [emitter setAlpha:0]; // add a second timer to remove it. [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(removeEmitter) userInfo:nil repeats:NO]; } return self; } 

我正在构建一个Spritekit应用程序。 该应用程序不规则地崩溃,没有调试信息只留下指向可怕的SKSpinLockLock的指针。 该应用程序在一组复杂的“动画”动作中崩溃。 就像R.Randazzo在他的post中提到的那样,懒惰的图像加载可能会导致这些问题。 但我的所有动画都使用预装的图像。 最终我发现了一个“隐藏在阴影中”的延迟加载图像,等待作为我的动画序列和用户交互的结果呈现。 在预加载此图像后,SKSpinLockLock鬼魂也消失了。 NB我正在为IOS 7 +开发