gpt4 book ai didi

lua - 自引用用户数据和垃圾回收

转载 作者:行者123 更新时间:2023-12-04 19:13:03 27 4
gpt4 key购买 nike

因为我的userdata对象引用了它们自己,所以我需要删除和设置一个变量以使垃圾回收器正常工作。

Lua代码:

obj = object:new()
--
-- Some time later
obj:delete() -- Removes the self reference
obj = nil -- Ready for collection


C代码:

typedef struct {
int self; // Reference to the object
int callback; // Reference to a Lua function
// Other members and function references removed
} Object;

// Called from Lua to create a new object
static int object_new( lua_State *L ) {
Object *obj = lua_newuserdata( L, sizeof( Object ) );

// Create the 'self' reference, userdata is on the stack top
obj->self = luaL_ref( L, LUA_REGISTRYINDEX );

// Put the userdata back on the stack before returning
lua_rawgeti( L, LUA_REGISTRYINDEX, obj->self );

// The object pointer is also stored outside of Lua for processing in C

return 1;
}

// Called by Lua to delete an object
static int object_delete( lua_State *L ) {
Object *obj = lua_touserdata( L, 1 );

// Remove the objects self reference
luaL_unref( L, LUA_REGISTRYINDEX, obj->self );

return 0;
}

// Called from Lua to set a callback function
static int object_set_callback( lua_State *L ) {
Object *obj = lua_touserdata( L, 1 );

// Unref an existing callbacks
if ( obj->callback != 0 ) {
luaL_unref( L, LUA_REGISTRYINDEX, obj->callback );
obj->callback = 0;
}

// Set the new callback - function is on top of the stack
obj->callback = luaL_ref( L, LUA_REGISTRYINDEX );
}

// Called from C to call a Lua function for the obj
static void do_callback( Object *obj ) {
// Push the Lua function onto the stack
lua_rawgeti( L, LUA_REGISTRYINDEX, obj->callback );

// Push the userdata onto the stack
lua_rawgeti( L, LUA_REGISTRYINDEX, obj->self );

// Call the function
lua_call( L, 1, 0 );
}


有什么办法可以在Lua中将对象设置为nil,并自动调用delete()方法?或者,删除方法是否可以将所有引用该对象的变量设为零?自我参照能否被“弱化”?

编辑1:我已经包含了代码,以显示为什么对象引用自身;请参阅do_callback函数。每个对象都是树状结构的一部分,大部分处理工作都是用C语言完成的,但是用户可以设置一个自定义Lua函数,该函数在某些条件下会被调用。

编辑2:想到另一个可能的解决方案;当需要将对象的地址作为键传递给Lua时,是否可以在全局索引中查找对象,而不是每个obj都对其自身进行引用?

最佳答案

您可以尝试在注册表中创建一个弱表并在其中存储您的引用,这样将对象的所有引用设置为nil即可使其可用于gc。

关于lua - 自引用用户数据和垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2755479/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com