因爲我的用戶數據對象引用自己,我需要刪除和零垃圾收集工作的一個變量。自參照用戶數據和垃圾收集
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爲零,並有自動調用了delete()方法?或者,刪除方法是否可以刪除引用該對象的所有變量?自我參照能力是否「虛弱」?
編輯1:我已經包含代碼,說明爲什麼對象引用本身;請參閱do_callback函數。每個對象都是樹狀結構的一部分,其中大部分處理是用C完成的,但用戶可以設置在某些條件下調用的自定義Lua函數。
編輯2:想到另一種可能的解決方案;而不是每個obj保持對自身的引用,當我需要將它的地址作爲關鍵字傳遞給Lua時,我可以在全局索引中查找對象嗎?
我不會給這個作爲一個正常的答案,因爲我不知道如何解決你的整個問題,但你看着Lua的__gc - 元方法? – ponzao 2010-05-03 05:21:33
userdata具有__gc回調;但直到在delete()中刪除自引用後纔會調用它,並且指向userdata的所有變量均爲零。 – 2010-05-03 05:56:38
爲什麼你需要一個自我參考?在C端可以存儲(Object *)obj,並依靠__gc清理;在Lua方面你有obj。 – 2010-05-03 15:44:47