2

I am currently having a weird intermittent issue with SpriteKit and SKTexture preloading. I have multiple arrays of images which I preload in the following format:

- (NSDictionary *)loadTexturesWithNames:(NSArray *)aNames
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSMutableArray *textureArray = [NSMutableArray array];

    for (NSString *textureName in aNames)
    {
        SKTexture *texture = [SKTexture textureWithImageNamed:textureName];
        if (texture)
        {
            [textureArray addObject:texture];
            [dict setObject:texture forKey:textureName];
        }
    }

    [SKTexture preloadTextures:textureArray withCompletionHandler:^{
        _iCounter++;
        [self loadTextures];
    }];

    return dict;
}

This works fine 90% of the time but occasionally I get the following error:

SKTexture: Error loading image resource:

This doesn't happen on any particular set of images, just randomly. So sometimes the player will load fine, and others it won't. Could this be a memory issue? I split the texture loading up using an _iCounter which makes sure the previous set of images loads before it starts the next to try and stop too much concurrent loading. This sped up the process but I still see this intermittent issue.

Has anyone else seen this, or have any idea what could cause this?

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
Elliott D'Alvarez
  • 1,217
  • 16
  • 30

1 Answers1

2

A common cause in my experience is when you don't wait for the completion handler to be called. For instance doing something like this where "image" is one of the images being preloaded would be possible source of error:

[self loadTexturesWithNames:names];
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithImageNamed:@"image"];

Of course if you create sprite nodes and texture only in the loadTexture method it should be fine. Unless you perform other background tasks or you run the loadTextureWithNames selector in the background (separate thread).

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
  • Hi, when preloading the textures is there overhead for storing a reference to them like I currently do? I.e. is it better to simply load the textures and then call [SKSpriteNode spriteNodeWithImageNamed:@"image"] like you do? I do not use any of the textures until all the images have been preloaded but will double check that this isn't the issue by completely separating the call. – Elliott D'Alvarez Dec 04 '14 at 13:26
  • 1
    Hmmm your textureArray is released once the loadTexturesWithNames: method returns, and the array isn't passed in to loadTexture either. This might actually null and void the preloading, depending on how texture caching is implemented in Sprite Kit. – CodeSmile Dec 04 '14 at 13:29
  • I think you may have hit the nail on the head there, I've stored it in an overall retained array and it seems to load fine now. Thanks for the help. – Elliott D'Alvarez Dec 05 '14 at 11:26