Кэширование предварительной загрузки памяти SpriteKit и проблема с fps
Мой вопрос довольно прост, согласно Apple Docs, у вас есть возможность предварительно загружать текстуры в оперативную память до представления сцены следующим образом:
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. Сбой - это exec_bad_access при вызове Sprite::update(double), поэтому я предполагаю, что каким-то образом текстуры из первой предварительной загрузки были удалены из ОЗУ, и поэтому я предварительно загружаю каждый раз, когда создаю новый узел. Кажется, это исправило эту ошибку. Это приводит к другой проблеме, хотя, когда речь идет о производительности и, следовательно, причина, почему я спрашиваю об этом.
Игра отлично работает на 5S и 5, но как только вы дотрагиваетесь до iPod touch 5-го поколения, она едва может превысить 15 FPS. Я запускал инструменты, и это то, что поглощает все процессорное время:Может ли это быть связано с моим постоянным вызовом вызова preloadatlas? Кто-нибудь знает, почему это будет так сильно загружать мое процессорное время на старых устройствах? Большое спасибо и, надеюсь, у кого-то еще может быть похожая проблема, и это поможет им, как только я доберусь до сути.
Заранее спасибо.
1 ответ
Предварительная загрузка атласов при каждом создании нового спрайта - плохая идея.
Ваша настоящая проблема заключается в том, что вы предварительно загружаете атласы, но не держите их рядом. Если переменные атласа не являются глобальными.
Как только метод, выполняющий предварительную загрузку, возвращается, на объекты атласа теперь больше ссылаются, и они автоматически удаляются из памяти. В Sprite Kit встроена система кеширования, поэтому вы не сразу заметите это, но в конечном итоге один или несколько атласов исчезнут.
Держите строгую ссылку на каждый атлас в вашей сцене, чтобы атласы оставались в памяти и прекратили предварительную загрузку во время выполнения. Помогает ли это с fps, я не знаю.