SpriteKit内存管理预加载缓存和fps问题

时间:2014-01-13 18:42:32

标签: ios sprite-kit

我的问题非常简单,根据苹果文档,您可以在呈现像这样的场景之前将纹理预加载到RAM中:

SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:@"effect_circle_explode"];
SKTextureAtlas * atlas2 = [SKTextureAtlas atlasNamed:@"box_explodes"];
SKTextureAtlas * atlas3 = [SKTextureAtlas atlasNamed:@"fence_new"];
SKTextureAtlas * atlas4 = [SKTextureAtlas atlasNamed:@"swipe"];
SKTextureAtlas * atlas5 = [SKTextureAtlas atlasNamed:@"coin"];
SKTextureAtlas * atlas6 = [SKTextureAtlas atlasNamed:@"two_times"];
SKTextureAtlas * atlas7 = [SKTextureAtlas atlasNamed:@"three_times"];
SKTextureAtlas * atlas8 = [SKTextureAtlas atlasNamed:@"gus"];

[SKTextureAtlas preloadTextureAtlases:@[atlas, atlas2, atlas3, atlas4, atlas5, atlas6, atlas7, atlas8] withCompletionHandler:^{

    [moron_logo removeFromSuperview];
    moron_logo = NULL;

    stuff.hidden = NO;
    store.hidden = NO;

    scroll_view.userInteractionEnabled = YES;

    [self present_game_view];


}];

如果以后通过游戏玩法你也会对这样的地图集进行预加载会产生任何负面影响:

-(void)load
{

SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:@"effect_circle_explode"];
SKTextureAtlas * atlas2 = [SKTextureAtlas atlasNamed:@"coin"];

[SKTextureAtlas preloadTextureAtlases:@[atlas, atlas2] withCompletionHandler:^{

explode_textures = [[NSMutableArray alloc] init];
int numImages = (int)atlas.textureNames.count;
for (int i=0; i <= numImages/2-1; i++)
{
    NSString *textureName = [NSString stringWithFormat:@"effect_circle_explode_%d.png", i];
    SKTexture *temp = [atlas textureNamed:textureName];
    [explode_textures addObject:temp];
}

explodeAnimation = [SKAction animateWithTextures:explode_textures timePerFrame:.05];

idle_textures = [[NSMutableArray alloc] init];
int numImages2 = (int)atlas.textureNames.count;
for (int i=0; i <= numImages2/2-1; i++)
{
    NSString *textureName = [NSString stringWithFormat:@"coin_%d.png", i];
    SKTexture *temp = [atlas2 textureNamed:textureName];
    [idle_textures addObject:temp];
}


idleAnimation = [SKAction animateWithTextures:idle_textures timePerFrame:.05];

[self animate:0];

}];


}

现在如果我不再预加载纹理,如果我只是将纹理直接插入SKAction,游戏实际上会偶尔崩溃一次。崩溃是Sprite :: update(double)调用的exec_bad_access,所以我的假设是从第一次预加载的纹理以某种方式从RAM中删除了,这就是为什么我现在每次创建一个新节点时都会预加载。它似乎修复了这个错误。这导致另一个问题,但是当涉及到性能时,因此我问这个问题。

游戏在5S和5上运行良好但是一旦你触摸iPod touch第5代,它几乎不能超过15 FPS。我运行了仪器,这就是耗费所有CPU时间: enter image description here 这可能与我不断调用preloadatlas调用有关吗?有谁知道为什么这会在旧设备上如此严重地耗尽我的处理器时间?非常感谢,并希望其他人可能遇到类似的问题,一旦我走到最底层,这将帮助他们。

提前致谢。

1 个答案:

答案 0 :(得分:10)

每次创建新精灵时预加载地图通常都是一个坏主意。

你的实际问题似乎是你预装了地图集,但你没有把它们留在身边。除非地图集变量是全局的。

一旦执行预加载的方法返回,atlas对象现在被更长时间引用,并将自动从内存中删除。 Sprite Kit在内部实现了一个缓存系统,因此您不会立即注意到它,但最终会有一个或多个地图集消失。

对场景中的每个地图集保持强烈的引用,以便地图集保留在内存中,并在运行时停止预加载。这是否有助于fps,我不知道。

相关问题