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

Krz*_*ski 9 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];


}];
Run Code Online (Sandbox Code Playgroud)

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

-(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];

}];


}
Run Code Online (Sandbox Code Playgroud)

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

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

提前致谢.

Lea*_*s2D 10

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

你的实际问题似乎是你预先加载了地图集,但是你没有保留它们.除非地图集变量是全局的.

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

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