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

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

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

最佳答案

在 lua 5.1 中,唯一与 __gc 元方法一起工作的 lua 值是 userdata。自然地,任何 hack 或解决方法都必须以某种方式涉及 userdata。通常没有办法只从 lua 端创建新用户数据,但是有一个“隐藏”未记录的函数 newproxy 可以做到这一点。

newproxy 采用可选的 bool 或 userdata 参数。如果你传入 true 那么你会得到一个附加了新元表的用户数据。如果您传入另一个 userdata,那么新的 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 在表上得到正式支持。

关于表的 __gc 元方法的 Lua 5.1 解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27426704/

相关文章:

c - 使用 Lua C 函数时减少重复的任何技巧

.NET:有什么方法可以判断对象何时被处理/垃圾收集?

c - 从 C/C++/Rust 设置 lua 表的方法

lua - Redis LUA脚本条件取错返回语句

actionscript-3 - 垃圾收集器在每一帧上占用所有 cpu 时间的原因

java - 在 Activity 的 onDestroy() 中使用 Runtime.getRuntime().gc() 方法是一种好习惯吗?

function - 为什么清除传递的表在函数作用域内不起作用?

lua - 从 Lua 中的表中减去表

sorting - 如何在记录原始位置的同时对表格进行排序?

c++ - 一个c++程序中可以有多少个lua_State