首先要了解lua的垃圾回收机制,lua中的垃圾回收机制是每隔一段时间清除不再被引用的对象,也就是说一个对象如果不再被使用就会在下次的gc中被回收掉,这个不需要我们管理,是lua中的自动回收机制。接下来看一下c++注册到lua的接口:
TOLUA_API void tolua_cclass (lua_State* L, const char* lname, const char* name, const char* base, lua_CFunction col)
{
char cname[128] = "const ";
char cbase[128] = "const ";
strncat(cname,name,120);
strncat(cbase,base,120);
mapinheritance(L,name,base);
mapinheritance(L,cname,name);
mapsuper(L,cname,cbase);
mapsuper(L,name,base);
lua_pushstring(L,lname);
push_collector(L, name, col);
/*
luaL_getmetatable(L,name);
lua_pushstring(L,".collector");
lua_pushcfunction(L,col);
lua_rawset(L,-3);
*/
//---- create a new class table, set it's metatable, and assign it to module
lua_newtable(L); // stack: module lname table
luaL_getmetatable(L,name); // stack: module lname table mt
lua_setmetatable(L, -2); // stack: module lname table
//Use a key named ".isclass" to be a flag of class_table
lua_pushliteral(L, ".isclass");
lua_pushboolean(L, 1);
lua_rawset(L, -3); // stack: module lname table
lua_rawset(L, -3); // stack: module
//---- by SunLightJuly, 2014.6.5
/* now we also need to store the collector table for the const
instances of the class */
push_collector(L, cname, col);
/*
luaL_getmetatable(L,cname);
lua_pushstring(L,".collector");
lua_pushcfunction(L,col);
lua_rawset(L,-3);
lua_pop(L,1);
*/
}
在c++对象注册到lua时一共有五个参数,这里主要说明最后一个参数,在上边的接口中第六行的函数实现如下:
static void push_collector(lua_State* L, const char* type, lua_CFunction col) {
/* push collector function, but only if it's not NULL, or if there's no
collector already */
if (!col) return;
luaL_getmetatable(L,type);
lua_pushstring(L,".collector");
/*
if (!col) {
lua_pushvalue(L, -1);
lua_rawget(L, -3);
if (!lua_isnil(L, -1)) {
lua_pop(L, 3);
return;
};
lua_pop(L, 1);
};
// */
lua_pushcfunction(L,col);
lua_rawset(L,-3);
lua_pop(L, 1);
};
lua中垃圾回收是在程序发生gc的时候,class_gc_event函数会去在lua对象的元表里面找".collector"这个key,如果没找到,就用default的析构,否则就用用户提供的析构函数。也就是这一段代码把最后的那个参数。此类对象则不需要用户自己再去管理内存的释放。否则若用户先释放了该对象,在gc中再次释放的时候便会报错。因为gc发生的时机可能在每一个时间,所以就会出现程序一直闪退,但是每次闪退的点都不一样,导致bug无法定位。所以要注意不要去管理此类对象的内存释放。
来源:CSDN
作者:beizijingzx
链接:https://blog.csdn.net/beizijingzx/article/details/103859004