3.1.1中Label的一个内存泄露问题及解决方法

对3.1.1进行二次封装的时候,发现了一个比较大内存泄露问题

Label控件,内部有一个_fontAtlas,用于组织所有的字符缓存材质

字体参数的改变setTTFConfig会重置这个_fontAtlas对象。
Label创建出来,第一次setTTFConfig,如果FontAtlasCache中没有相应的_fontAtlas,会新建一个FontAtlas,并调用setFontAtlas进行设置
此时_fontAtlas中会创建一个Texture2D,这个材质会经过以下调用

SpriteBatchNode::initWithTexture(_fontAtlas->getTexture(0), 30);

_reusedLetter = Sprite::createWithTexture(_fontAtlas->getTexture(0));

导致引用达到3

然后如果改变字体参数比如加入描边特性,_fontAtlas会被重置,此时旧的_fontAtlas应该被释放,但是,_fontAtlas中的材质却无法释放,原因如下
设置新的_fontAtlas之后,会调用Label::setFontAtlas中的

_reusedLetter->setTexture(_fontAtlas->getTexture(0));

但setTexture中

if (!_batchNode && _texture != texture)
{
CC_SAFE_RETAIN(texture);
CC_SAFE_RELEASE(_texture);
_texture = texture;
updateBlendFunc();

}

_batchNode是true,导致走不到这个分支,老的_fontAtlas中的材质就无法运行到release,缺少了一个release,导致一直挂起无法释放

改成如下

if (_texture != texture)
{
    CC_SAFE_RETAIN(texture);

CC_SAFE_RELEASE(_texture);
_texture = texture;
if (!_batchNode) updateBlendFunc();

}

解决问题。

感谢您的反馈,该问题已经向开发人员反馈。

已修正:https://github.com/cocos2d/cocos2d-x/pull/7044