Lua怎么注册userdata的__gc?

想问一下各位大大,quick-x的对象是用tolua++绑定的,然后还都没有指定collector,意思是用C++来管理Lua对象了

但是,如果我想在Lua里面做Cache,这样我就需要retain对象,避免被回收,但是在真正回收的时候,我还是需要调用autorelease,问题是怎么调用呢?我这么写:

function ud:delete() – whatever
self:release()
end

这样吗?怎么才能注册userdata的垃圾回收处理函数呢?

可以的。自己retain的话就自己release,还是和C++里一样注意对应就好了。

可是,我是问怎么在userdata(比如cc.Animation)被【垃圾回收】的时候,执行一个函数,Lua里面是可以的:

local t = newproxy(true)
getmetatable(t).__gc = function()
print(“这里会在所有Lua代码没用到t的时候,调用”)
end

我是想知道,cocos导出的userdata支不支持这样的功能,即,在userdata(而不是对象本身)被垃圾回收的时候,调用一个函数,让我在里面能autorelease。

产生这个需求的原因是做cache,弱表cache的时候你是不知道什么时候需要release的,直到对象没有Lua引用——这种情况下Lua会调用你的__gc元表方法,我是想知道__gc会不会调用userdata身上的某个方法,这样我就可以给每个userdata设置一个方法,用于release掉那个特定的userdata。

这当然是可以的,tolua导出时本来就带有__gc元表方法,你也可以自己重新设置这个方法。你可以查一下tolua_event.c里class_gc_event这个函数是如何调用的。

好的~非常感谢,我知道怎么写了 :slight_smile:

到时候做一个Animation的Cache(但是不需要蛋疼的plist文件),分享到论坛来:11:

阳光七月你好,请问一下,tolua本来导出的__gc方法里面都干了些什么呢?如果是重置__gc方法,因为userdata的metatable是共有的,那么就是说会影响其他拥有同样matatable的userdata?

请问楼主 应该怎么写呢?我也有类似的要做一个cache的需求。

tolua的gc方法里,如果类有自己的清理函数会去调用,否则调用默认的清理函数,实际上就是delete掉对象。
userdata的metatable其实不是共有的,不同的类是分开的。
具体还是自己看代码吧,修改其实不难。

非常感谢!
我还有一点不懂的是,你说tolua导出的__gc方法会默认delete掉对象,那既然userdata里面的C++对象(Node, Sprite等)都是create出来的,为什么还要delete掉呢?
还是说delete掉的不是C++对象而是userdata保存的那个4个字节的指针的内存吗?

cocos对create出来的对象,其userdata会记录到一个表中,因此不会被gc掉。在C++释放掉这个对象时,将userdata指向的对象指针置为NULL,再从表中移除userdata记录。因此create出来的对象,其userdata进到gc里的时候,指向的对象已经是NULL了。这就是楼主说的"用C++来管理Lua对象"的意思。
如果要修改,当然是要定义好自己的清理函数,然后先把userdata从上述表中先移除,这样在Lua中被GC时才能进入__gc方法。

嗯,很详细的解析,太感谢了!