原生平台spine造成的泄漏问题

问题描述: 在原生平台上使用spine时,如果在js端调用到某些特定接口,待spine释放后,js中会泄漏部分nativeptr对象。
举例:
spine::Slot类里面有两个Color成员和对应的访问接口:

public:
        Color &getColor();
	Color &getDarkColor();
private: 
   Color _color;
   Color _darkColor; 

我们来看下getColor和getDarkColor的binding函数:


static bool js_cocos2dx_spine_Slot_getDarkColor(se::State& s)
{
    spine::Slot* cobj = (spine::Slot*)s.nativeThisObject();
    SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_Slot_getDarkColor : Invalid Native Object");
    const auto& args = s.args();
    size_t argc = args.size();
    CC_UNUSED bool ok = true;
    if (argc == 0) {
        spine::Color& result = cobj->getDarkColor();
        ok &= native_ptr_to_rooted_seval<spine::Color>((spine::Color*)&result, &s.rval());
        SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_Slot_getDarkColor : Error processing arguments");
        return true;
    }
    SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
    return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_Slot_getDarkColor)

static bool js_cocos2dx_spine_Slot_getColor(se::State& s)
{
    spine::Slot* cobj = (spine::Slot*)s.nativeThisObject();
    SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_Slot_getColor : Invalid Native Object");
    const auto& args = s.args();
    size_t argc = args.size();
    CC_UNUSED bool ok = true;
    if (argc == 0) {
        spine::Color& result = cobj->getColor();
        ok &= native_ptr_to_rooted_seval<spine::Color>((spine::Color*)&result, &s.rval());
        SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_Slot_getColor : Error processing arguments");
        return true;
    }
    SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
    return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_Slot_getColor)

需要 注意的是上面两个binding函数中都用了native_ptr_to_rooted_seval这个接口,意味着result这个color对象在js中对应的js对象不能被js引擎gc,而只能由C++来管理内存释放。而Slot的_color, _darkColor成员的释放过程中并不会主动去NativePtrToObjectMap里面删除对应的js对象。因此造成泄漏。

类似的问题在spine里面还有多个,只需要满足以下要求 的就都可能出问题:

  1. 导出接口使用的是native_ptr_to_rooted_seval
  2. 实际的对象是作为类成员对象(不是指引)
  3. 在js中调用过这个binding的接口。
2赞

顶一个先!!!!!

前排关注:mahjong:

https://github.com/cocos-creator/cocos2d-x-lite/issues/2523 中跟踪问题

现在creator 2.4.11版本还有这问题