我在Lua中有如下代码:
mv.getLabelChildByNameSequence("confirm_btn|button|no_icon_txt").setVisible(false);
getLabelChildByNameSequence()
返回一个userdata
对象(在c端创建),然后setVisible()
对该对象调用一个函数。问题是,它在大多数时间都有效,但是有时,垃圾收集器决定在创建之后,语句的第二部分发生之前立即销毁中间对象。
我发现这更成功:
local no_icon_txt = mv.getLabelChildByNameSequence("confirm_btn|button|no_icon_txt");
no_icon_txt.setVisible(false);
我怀疑使用显式local
变量,引用计数按预期方式工作,并且直到局部变量超出范围才对对象进行垃圾回收。
相对于第二个示例,我更喜欢第一个示例-它更紧凑,更漂亮,并且更像您在c++
这样的语言中看到的内容。我该如何实现?
顺便说一句,当崩溃发生时,尽管只是垃圾收集了数据,但它似乎确实试图将对setVisible()
的调用解析为对象的旧内存地址。很好奇。
编辑:我要提到的是我使用LunaFive
进行绑定(http://lua-users.org/wiki/LunaFive)。用户数据推送fn如下所示:
static void push(lua_State * L, T* instance )
{
T **a = (T **) lua_newuserdata(L, sizeof(T *)); // Create userdata
*a = instance;
luaL_getmetatable(L, T::className);
lua_setmetatable(L, -2);
}
函数分派如下所示:
static int function_dispatch(lua_State * L)
{
int i = (int) lua_tonumber(L, lua_upvalueindex(1));
T** obj = static_cast < T ** >(lua_touserdata(L, lua_upvalueindex(2)));
return ((*obj)->*(T::methods[i].func)) (L);
}
getLabelChildByNameSequence()
推送Label
类的一个新实例(比方说),而setVisible()
是该类的一个方法。
答案 0 :(得分:0)
根据对我的问题的评论中的反馈,我所做的事情被删除了函数分派中的lua_upvalueindex()
业务,而是要求将userdata作为函数回调的第一个参数。然后,我将点表示法切换为冒号表示法,并提供了隐式self
。从那以后再也无法重现崩溃。
我仍然不明白为什么在函数调用之前没有正确地对upvalue进行计数。也许在对象创建中缺少一些东西。