Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么要将userdata对象添加到这个Lua 5.1\u gc解决方案中的表中?_Lua_Garbage Collection - Fatal编程技术网

为什么要将userdata对象添加到这个Lua 5.1\u gc解决方案中的表中?

为什么要将userdata对象添加到这个Lua 5.1\u gc解决方案中的表中?,lua,garbage-collection,Lua,Garbage Collection,我正在寻找在Lua5.1中向我的表(对象)添加垃圾收集的解决方案。我发现可以使用newproxy()和\uu gc解决这个问题: 我不明白的是作者使用了将userdata作为字段插入表中 通过此包装器设置元表的所有对象都会被特殊键\uuu gc\u proxy“污染”(可以是任何字符串,用户可通过\uu gc\u proxy global定义)。如果遍历表的字段(next(),pairs()…),则必须对其进行特殊处理 及 在使用建议的解决方案时,有一件事需要关注——如果您将通过pairs(

我正在寻找在Lua5.1中向我的表(对象)添加垃圾收集的解决方案。我发现可以使用
newproxy()
\uu gc
解决这个问题:

我不明白的是作者使用了将userdata作为字段插入表中

通过此包装器设置元表的所有对象都会被特殊键\uuu gc\u proxy“污染”(可以是任何字符串,用户可通过\uu gc\u proxy global定义)。如果遍历表的字段(next(),pairs()…),则必须对其进行特殊处理

在使用建议的解决方案时,有一件事需要关注——如果您将通过pairs()遍历表,您将得到一个加法键。通过使用具有适当元方法的代理对象代替原始表,可以避免这种情况

下面是堆栈溢出线程的复制/粘贴示例:

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)

for k, v in pairs(test) do
   print(tostring(k) .. " " .. tostring(v))
end
输出为:

userdata: 0003BEB0 true
cleaning up:    table: 00039D58
但此清理是从脚本结尾开始的,而不是在调用
collectgarbage()
时进行的

这可以通过一个以循环结束的稍加修改的版本来证明。输出应为“清理”:

相反,通过删除有问题的
t[prox]=true
,集合可以按预期工作:

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

function gctest(self)
   print("cleaning up")
   io.flush()
end

test = setmt__gc({}, {__gc = gctest})
collectgarbage()

while (true) do
end
输出:

cleaning up

但此清理是从脚本结束时开始的,而不是在调用collectgarbage()时进行的。
-发生这种情况的原因是全局变量
test
锚定表,因此在程序退出之前无法对表进行垃圾收集
,但此清理是从脚本结束时开始的,而不是在调用collectgarbage()时进行的
-发生这种情况的原因是全局变量
test
锚定表,因此在程序退出之前无法对表进行垃圾收集
cleaning up