3

我目前面临的问题是您不能__gc在 Lua 5.1 中使用表的方法,因为它们是在 Lua 5.2 中实现的。但是,一旦收集了 lua 表,我想释放分配的本机资源。是否可以制定一种解决方法,让我__gc在 Lua 5.2 中为 Lua 5.1 提供元方法的功能?

4

1 回答 1

4

在 lua 5.1 中,唯一可以使用元方法的 lua 值__gcuserdata. 自然,任何黑客或解决方法都必须以某种方式参与userdata。通常没有办法从 lua 端创建 newuserdata,但是有一个“隐藏的”未记录的函数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 演示

newproxy请注意,lua 5.2+及更高版本不再具有__gc表的官方支持。

于 2014-12-11T21:53:18.520 回答