Sprite Kit 中的 SKSpinLockSync 是什么以及如何修复它 [英] What is SKSpinLockSync in Sprite Kit and how do I fix it
问题描述
我收到了包含以下堆栈跟踪的错误报告,但我不知道问题出在哪里.我已经看到一些建议,这可能是由于在纹理图集中使用了发射器的图像,或者在添加发射器时在同一运行循环中移除了发射器,但我认为这两种情况都不会发生.这是一个零星的问题,我无法重新创建它.我只在错误报告中看到它.我很乐意提供任何帮助.
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屋!