What is SKSpinLockSync in Sprite Kit and how do I fix it

前端 未结 7 849
忘了有多久
忘了有多久 2021-01-05 10:43

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

相关标签:
7条回答
  • 2021-01-05 11:16

    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;
    }
    
    0 讨论(0)
  • 2021-01-05 11:18

    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  
    

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

    My solution is : don't call unarchiveObjectWithFile everytime

    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.

    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];
    }
    
    0 讨论(0)
  • 2021-01-05 11:18

    I am building a Spritekit app. The app crashed irregularly with no debug info only leaving a pointer to the dreaded SKSpinLockLock. The app crashed in the middle of a complex set of "animation" actions. Like R.Randazzo mentioned in his post, lazy image loading could cause these problems. But all my animations are using preloaded images. Eventually I discovered a lazy loading image "hiding in the shadow", waiting to be presented as the result of my animation sequence and user interaction. After preloading this image too, the SKSpinLockLock ghost was gone. N.B. I am developing for IOS 7 +

    0 讨论(0)
  • 2021-01-05 11:25

    I had a similar problem in making a game using SpriteKit. All postings to be able to be obtained from internet search was void to the solution. Sometimes, a special action type would cause this problem, not by corrupt or missing texture in the bundle if the action contains a concept of multithreading. And I did solve it! In other words, indirectly your code might have a kind of multi-threading even though there seems none of apparent multi-threads.

    0 讨论(0)
  • 2021-01-05 11:28

    OSSpinLock is a mechanism to ensure atomic operations in multithreaded apps.

    I don't think there's a multithreading issue here, but rather loadImageData may have provided data that crashes during the atomic part of the work. This could be due to a missing (or corrupt or unsupported file format) texture in the bundle. It is certainly an emitter that causes the texture load to fail.

    Try testing your app in release configuration (edit the scheme) for a while. Some bugs only surface in release builds with optimizations enabled. You could also build an adhoc version of your app and deploy it to your device and test it. Your first goal right now should be to verify the issue on your own device, otherwise it may be hard to pin down.

    The call stack does give you a few hints: the problem is with a emitter that is a child of a sprite which is a child of another sprite which is a child of the scene. Perhaps that narrows it down.

    0 讨论(0)
  • 2021-01-05 11:30

    I had this exact problem (same crash log stack) with particles in Sprite Kit. I tried many things over many hours -- and finally figured it out, sorta: it seemed to be because the source texture was in a Texture Atlas folder, and it didn't have the corresponding @2x image. Try moving the texture out of the texture atlas and/or adding an @2x version of the image.

    0 讨论(0)
提交回复
热议问题