问题引出
- 有些Lua项目,为了解决循环强引用无法释放类(table),需要程序员手动回收内存Delete类,这是在开历史倒退车。
- 出现循环强引用时,只需要使用Weak Table(http://www.lua.org/manual/5.1/manual.html#2.10.2)来规避。这样就可以无障碍地使用此文章下面提到的基础类,无需手动回收内存Delete类,面向对象开发lua
目录结构
Base/BaseClass.lua
Base/Example/Parent.lua
Base/Example/Child.lua
Base/Example/Grandson.lua
类的详细代码
BaseClass.lua
--Lua5.1 __gc方法(Lua5.2开始才支持直接设置__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
--输出日志--
function log(...)
print(...)
end
--错误日志--
function logError(...)
print(...)
end
--警告日志--
function logWarn(...)
print(...)
end
local _class = {}
function class(base)
local class_type = {}
local vtbl = {} -- construct virtual table
_class[class_type] = vtbl
setmetatable(class_type, {__newindex=
function(t, k, v)
vtbl[k] = v
--rawset(t, k, v) -- add by Dream^2
end,
__index = function (t, k)
return vtbl[k]
end})
class_type.ctor = false
class_type.base = base
--class_type.new = function (...) --Comment by liboxiang
function class_type:new (...) -- Add by liboxiang
local obj = {}
--Lua5.1 __gc方法
setmt__gc(obj, {__gc=function(target)
logWarn("__gc函数执行")
do
local decreate -- a function use for recursion to base class
decreate = function(c)
if c.dtor then
c.dtor(target)
end
if c.base then
decreate(c.base)
end
end
decreate(class_type)
end
end})
--為了可以在 class:ctor()函數里 ,可以冒號調用self:func(),放到這裡來
-- setmetatable(obj, {__index=vtbl})
getmetatable(obj).__index = vtbl
do
local create -- a function use for recursion to base class
create = function(c, ...)
if c.base then
create(c.base, ...)
end
if c.ctor then
c.ctor(obj, ...)
end
end
create(class_type, ...)
end
return obj
end
if base then
setmetatable(vtbl, {__index =
function(t, k)
--print("--" .. tostring(t) .. " k:" .. tostring(k))
local ret=_class[base][k] --为了追溯父类的成员
vtbl[k]=ret
return ret
end})
end
return class_type
end
Parent.lua
Parent = class()
function Parent:ctor( ... )
logWarn("Parent:ctor( ... )")
end
function Parent:dtor( )
logWarn("Parent:dtor()")
end
Child.lua
require "Base/Example/Parent"
Child = class(Parent)
function Child:ctor( ... )
logWarn("Child:ctor( ... )")
end
function Child:print()
logWarn("Child:print()")
end
function Child:dtor( )
logWarn("Child:dtor()")
end
Grandson.lua
require "Base/Example/Child"
Grandson = class(Child)
function Grandson:ctor( name )
logWarn("Grandson:ctor(name=" .. name .. ")")
end
function Grandson:print()
logWarn("Grandson:print()")
Grandson.base.print(self)
end
function Grandson:dtor( )
logWarn("Grandson:dtor()")
end
使用例子
logError("BaseClass 例子开始")
require "Base/BaseClass"
require "Base/Example/Grandson"
local grandson = Grandson:new("Tom")
grandson:print()
grandson = nil
collectgarbage("collect") -- 强制垃圾回收
logError("BaseClass 例子结束")
--输出日志如下:
--BaseClass 例子开始
--Parent:ctor( ... )
--Child:ctor( ... )
--Grandson:ctor(name=Tom)
--Grandson:print()
--Child:print()
--__gc函数执行
--Grandson:dtor()
--Child:dtor()
--Parent:dtor()
--BaseClass 例子结束
Unity例子工程链接
链接:https://pan.baidu.com/s/1Sv32_q_cvk7HU79Bvd-h5w
提取码:c6q8
例子场景为:Assets\LuaFramework\Scenes\main.unity










网友评论