用于表的__gc元方法的Lua 5.1解决方法

时间:2014-12-11 15:41:08

标签: lua garbage-collection lua-table lua-5.1

我目前面临的问题是你不能在Lua 5.1中对表使用__gc方法,因为它们是在Lua 5.2中实现的。但是,我想在收集lua表后释放已分配的本机资源。是否有可能为Lua 5.1中的Lua 5.2提供__gc metamethod功能的解决方法?

1 个答案:

答案 0 :(得分:3)

在lua 5.1中,使用__gc元方法的唯一lua值为userdata。当然,任何黑客攻击或解决方法都必须涉及userdata。通常情况下,没有办法从lua端创建newuserdata,但只有一个“ hidden ”未记录的函数newproxy就可以做到这一点。

newproxy采用可选的bool或userdata参数。如果您传入true,那么您将获得一个附加了新元谱的用户数据。如果您传入另一个userdata,那么新的用户数据将被分配与传入的相同的元数据。

所以现在你可以将一个能使__gc工作的函数组合在一起:

function setmt__gc(t, mt)
  local prox = newproxy(true)
  getmetatable(prox).__gc = function() mt.__gc(t) end
  t[prox] = true
  return setmetatable(t, mt)
end

快速测试确认行为:

iscollected = false
function gctest(self)
  iscollected = true
  print("cleaning up:", self)
end

test = setmt__gc({}, {__gc = gctest})
collectgarbage()
assert(not iscollected)

test = nil
collectgarbage()
assert(iscollected)

IDEOne Demo

请注意,lua 5.2+及更高版本不再具有newproxy,因为表格上正式支持__gc