创建匿名用户数据变量

Creation of anonymous userdata variables

我正在使用 lua C api 到 运行 与本机类交互的脚本。我正在利用 Qt 的 MOC 获取 运行 时间类型信息。到目前为止,我已经实现了我希望 lua 能够与之交谈的所有 classes 的创建、删除和索引。

这是我现在可以执行的示例脚本:

myObject = MyClass.new()  --creates new userdata
otherObject = OtherClass.new()  --creates new userdata

myObject:functionForOthers(otherObject)  --method that takes userdata as argument

在该脚本中,otherObject 被创建并保留在堆栈中。然后通过接受 OtherClass 个对象作为参数的 functionForOthers() 传递。

但是如果我不希望 otherObject 被放入堆栈怎么办?如果我希望它是一个仅存在于函数调用范围内的匿名变量怎么办?

myObject = MyClass.new()

myObject:functionForOthers(OtherClass.new())

这仍然有效,但 OtherObject 实例已创建,但 从未分配给变量 使其在堆栈上无法访问,直到范围结束。这不会导致任何直接问题,但它会困扰我的内存效率部分。

我有很多本机代码处理这些操作的后端,但其基本要点是 new 是全局表 MyClassOtherClass 的一个字段指向本机 CreateObject 函数。在调用 lua_newuserdata()

之后,从那里创建 class 的实例并将其存储在用户数据中

functionForOthers() 调用使用指向本地 IndexObject 函数的 __index 元方法,如果存在则调用该方法。

实现匿名用户数据变量的基本方法是什么?我仍然希望这两个脚本都是有效的方法,我只想要一种方法来将第二个脚本的 OtherClass 对象保持在范围内,直到函数调用完成。

感觉你对Lua的某些部分有误解。

将某个对象作为参数传递给函数不会 "leave" 该对象在堆栈上。堆栈只存储对对象的引用。对同一对象的另一个引用存储在 otherObject 变量中。当您将变量作为参数传递给 functionForOthers() 时,您会将该引用按值复制到堆栈中,并且一旦调用函数 returns control.

,该引用就会从堆栈中弹出。

对象本身存储在 Lua 堆上。它最终会得到 destroyed/collected ,当垃圾收集器发现没有留下对该对象的引用时。该对象不会在范围末尾销毁,只会丢失引用。何时真正删除对象取决于垃圾收集器。

如果担心内存不足,可以定期调用collectgarbage()。不过,这可能会使您的程序卡顿一段时间,因此请选择合适的时机。否则你可以完全忽略它,只要确保你没有收集对某些长期存在的结构(全局变量、注册表或你自己的dictionaries/caches)中的对象的引用。堆栈上的引用会被快速删除,除非您无意中创建了非常深或无限的递归调用。无法到达的对象将被自动删除,这就是标记清除垃圾收集器的工作方式。