正在与该软件作者取得联系,暂时是个人看法,得到作者回复后再更新。
在项目中,处理动画用的是 animation packer 的工具,但是使用中发现,加载动画再释放动画之后,会造成内存泄露,百思不得其解。
怒跟代码之后发现如下地方:
CCDictionary *AnimatePacker::loadAnimations(const char *path ) { ...... CCAnimation *animation = CCAnimation::createWithSpriteFrames(spriteFramesArray, animate.delay);//CCAnimation::createWithSpriteFrames(spriteFramesArray,animate.delay); CCAnimationCache::sharedAnimationCache()->addAnimation(animation,animate.name.c_str()); spriteFramesArray->removeAllObjects(); ...... return ret; }
这是loadAnimation的地方,注意CCAnimationCache里面的key。
void AnimatePacker::freeAnimations(const char *path) { ...... set<string> animateNames=pathToNameMap[path]; for (set<string>::iterator strItr=animateNames.begin();strItr!=animateNames.end();++strItr) { CCAnimationCache::sharedAnimationCache()->removeAnimationByName((*strItr).c_str()); nameToAnimateMap.erase((*strItr)); } pathToNameMap.erase(path); }
这是free的地方,最后会发现两个key不一样。所以导致cache里面的资源没有被清理
解法如下:
CCDictionary *AnimatePacker::loadAnimations(const char *path ) { ...... for (unsigned int i=0;i<animates.size();i++) { ...... for (unsigned int j=0;j<spriteFrames.size();j++) { //animateNames.insert(spriteFrames[j]); CCLOG("spriteFrames[j] = %s", spriteFrames[j].c_str()); CCSpriteFrame *spriteFrame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(spriteFrames[j].c_str()); // CCLOG("spriteFrame = %p", spriteFrame); spriteFramesArray->addObject(spriteFrame); } animateNames.insert(animate.name); ...... } return ret; }
将load函数中,双层for里面的内层for循环做如上修改。
或者在动画使用完成,不需要再使用之后,purgeCache。