关于3.8.1SpriteFrameCache优化方面的问题

注意看 SpriteFrameCache::addSpriteFramesWithDictionary()的实现


void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Texture2D* texture)
{
        ...

    auto textureFileName = Director::getInstance()->getTextureCache()->getTextureFilePath(texture);
    auto image = new Image();
    image->initWithImageFile(textureFileName);
    
    ...
}

使用SpriteFrameCache创建精灵帧缓存的时候
即使使用了 TextureCache::addImage 或 TextureCache::addImageAsync实现预加载了纹理
局部变量image的image->initWithImageFile(textureFileName);仍然要重新读取纹理数据, 这样效率会不会太低了?
这样的话,采用合图的纹理文件,岂不是都要读取2次
这一块是不是应该优化一下呢

addSpriteFramesWithDictionary 这个方法外部一般不会主动调用,建议你把整个SPriteFrameCache的加载看下,不要只看一个方法就下结论

是这样的, 我有个合图文件, a.png,
在加载场景 调用纹理异步加载函数 Director::getInstance()->getTextureCache()->addImageAsync(“a.png”, CC_CALLBACK_1(LoadingScene::LoadingCallback, this));
在游戏场景初始化的时候创建帧缓存, 调用 SpriteFrameCache::getInstance()->addSpriteFramesWithFile(“a.plist”, “a.png”); 在这里就会再次从IO读取a.png的数据, 加上上面的异步操作, 就算2次了
3.6版本是不会的

addSpriteFramesWithFile内部会判断纹理是否已经存在,如果你没等LoadingCallback回调完成就去创建spriteframe,当然要加载2次了

加载场景都把资源加载完毕了才进入的游戏场景, 所以异步操作肯定是完成了的
你可以测试一下,直接调用同步加载纹理:
Director::getInstance()->getTextureCache()->addImage(“a.png”);
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(“a.plist”, “a.png”);
加载一个4M左右的纹理这两行代码都明显卡顿
他们都调用了 Image::initWithImageFile(textureFileName); 从IO加载数据
另外补充一下,我测试的平台是win32