关于cocos2d: SpriteFrameCache: removing unused frame与内存警告,程序崩溃

本文介绍在Cocos2d-x 3.7.1版本中使用SpriteFrame预加载大图时遇到的问题及解决方案。若加载的大图未立即使用,在iOS设备收到内存警告时可能会被移除,导致后续无法获取图片。解决办法是将SpriteFrame加入自定义容器以增加其引用计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

version cocos2dx-3.7.1

使用SpriteFrame预加载合成的大图,如果没有马上使用,当收到ios的内存警告时就会被移除,后面再获取里面的图片时就会取不到,导致程序崩溃。解决方案为加载大图后,把里面的小图都加到自己定义的一个容器里,使其引用计数加一,避免被移除。

添加到自定义容器代码

void ResourceManager::addSpriteFramesWithFile(const std::string& plist, const std::string& textureFileName)
{
    SpriteFrameCache* cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile(plist, textureFileName);
    
    // ResourceManager的_spriteFrames容器也放一份,增加SpriteFrame引用计数,避免发生内存警告时被cocos引擎移除
    FileUtils* fu = FileUtils::getInstance();
    std::string fullPath = fu->fullPathForFilename(plist);
    ValueMap dict = fu->getValueMapFromFile(fullPath);
    ValueMap& framesDict = dict["frames"].asValueMap();
    for (auto iter = framesDict.begin(); iter != framesDict.end(); ++iter)
    {
        std::string spriteFrameName = iter->first;
        SpriteFrame* spriteFrame = cache->getSpriteFrameByName(spriteFrameName);
        _spriteFrames.insert(spriteFrameName, spriteFrame);
    }
}

引擎代码:

void SpriteFrameCache::removeUnusedSpriteFrames()
{
    bool removed = false;
    std::vector<std::string> toRemoveFrames;
    
    for (auto iter = _spriteFrames.begin(); iter != _spriteFrames.end(); ++iter)
    {
        SpriteFrame* spriteFrame = iter->second;
        if( spriteFrame->getReferenceCount() == 1 ) // 引用计数为1时就移除
        {
            toRemoveFrames.push_back(iter->first);
            spriteFrame->getTexture()->removeSpriteFrameCapInset(spriteFrame);
            CCLOG("cocos2d: SpriteFrameCache: removing unused frame: %s", iter->first.c_str());
            removed = true;
        }
    }

    _spriteFrames.erase(toRemoveFrames);

    // FIXME:. Since we don't know the .plist file that originated the frame, we must remove all .plist from the cache
    if( removed )
    {
        _loadedFileNames->clear();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值