6

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

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

4

7 回答 7

5

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

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 的问题,希望苹果能尽快解决这个问题

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

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

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

// 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];
}
于 2014-01-28T03:43:10.240 回答
2

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

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

[SKAction animateWithTextures: timePerFrame:]

我不确定原因是什么,但我的直觉是它与未预加载的纹理有关。该方法的文档没有提供关于是否必须预加载它们的任何见解,所以这纯粹是推测,但从我收集到的 SpriteKit 似乎令人窒息,因为它无法足够快地加载图像以显示它们。

无论如何,使用[SKTexture preloadTextures:...完全解决了我的崩溃

希望它对您和其他人也有帮助!

于 2014-02-25T21:40:22.227 回答
2

OSSpinLock是一种确保多线程应用程序中的原子操作的机制。

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

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

调用堆栈确实给了您一些提示:问题在于发射器是精灵的子精灵,而精灵是场景子精灵的子精灵。也许这会缩小范围。

于 2013-10-18T13:06:16.593 回答
0

If using SKEmitterNode and create more than 1 at the same time (close around the same time), my game still crashed. I had to manually preload (create and add emitter to scene), by then I was able to prevent the crashing I had to let the particle effect to be created and added to the scene and let it run its action. I then set the particle alpha to 0, to hide it. By then I was By Disappointment, I preloaded everything.

Using SKEmitterNode and getEmitter method above, I still getting crashes when I create more than 1 emitter around the same time. I solve this by creating one of the particle on the start, add it to the scene, and set its alpha to 0. This is a jacky way and it blows, but it works and doesn't crash.

Example:

@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;
}
于 2014-10-26T04:30:01.767 回答
0

我在 Sprite Kit 中遇到了这个确切的问题(相同的崩溃日志堆栈)。我花了好几个小时尝试了很多东西——终于弄明白了,有点像:这似乎是因为源纹理位于 Texture Atlas 文件夹中,并且没有相应的 @2x 图像。尝试将纹理移出纹理图集和/或添加图像的@2x 版本。

于 2014-01-21T21:01:01.310 回答
0

我在使用 SpriteKit 制作游戏时遇到了类似的问题。能够从互联网搜索获得的所有帖子对解决方案都是无效的。有时,如果动作包含多线程概念,则特殊动作类型会导致此问题,而不是由于捆绑中的纹理损坏或丢失。我确实解决了它!换句话说,即使似乎没有明显的多线程,您的代码也可能间接地具有一种多线程。

于 2013-11-12T16:32:20.120 回答
-1

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

于 2015-01-11T11:32:37.037 回答