Lua弱表
类型和引用类型
- Lua有8种基本类型:nil、boolean、number、string、function、userdata、thread、table
- 对象object:Tables、functins、threads、userdata, 其变量为引用类型
- 引用类型:赋值、参数传递、函数返回等都操作的是这些值的引用,并不产生任何copy行为
- nil的主要用途就是一个所有类型之外的类型,用于区别其他7中基本类型
垃圾回收机制
- gc自动运行,也可以手动调用
- 自动收集的目标是引用计数为0的对象
- dead objects:不能访问到的对象,没有引用指向它了,当然就是访问不到的了,也就等同于垃圾内存了。
弱表
- weak表是一个表,它拥有metatable,并且metatable定义了__mode字段
- weak表中的引用是弱引用(weak reference),弱引用不会导致对象的引用计数变化。换言之,如果一个对象只有弱引用指向它,那么gc会自动回收该对象的内存。
- __mode字段可以取以下三个值:k、v、kv
-
- k表示table.key是weak的,也就是table的keys能够被自动gc
-
- v表示table.value是weak的,也就是table的values能被自动gc
-
- kv就是二者的组合
-
- 任何情况下,只要key和value中的一个被gc,那么这个key-value pair就被从表中移除了
Demo:对value的弱引用
function createWeakTable(mode,tb)
tb=tb or {}
b={}
b.__mode = "v" -- value的弱引用
setmetatable( tb , b ) -- tb={ }的值就是弱引用 相当于 setmetabale( { } , { __mode = "v" } )
return tb
end
function createWeakTable(mode,tb)
tb = tb or {}
setmetatable( tb, { __mode = mode })
return tb
end
function printName(tb)
for i,obj in pairs(tb) do
print(obj.name)
end
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
end
objMapMem = createWeakTable( 'v' ) -- createWeakTable创建了一张弱表objMapMem
---------- 把所有玩家放到弱表 objMapMem里面
--objMapMem = { [ nAccountId ] = objHero, } -- 地图玩家 objMapMem 是一张表
local objHero1 = { id = 1, name = "obj1" }
local objHero2 = { id = 2, name = "obj2" }
local hero = objHero1 -- 对objHero1引用
objMapMem[ objHero1.id ] = objHero1
objMapMem[ objHero2.id ] = objHero2
---------- 遍历objMapMem打印所有玩家的名字
printName( objMapMem )
---------- 取消{ id = 1, name = "obj1" } 的objHero1引用
objHero1 = nil
collectgarbage()
printName( objMapMem )
---------- 取消{ id = 1, name = "obj1" } 的所有引用
objHero1 = nil
hero = nil
collectgarbage()
printName( objMapMem )
程序执行的结果:
obj1
obj2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
obj1
obj2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
obj2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
objMapMem[ objHero2.id ] = objHero2
- 这样创建的objMapMem是张弱表, 其他地方对value的引用取消了 , 这个objMapMem的字段也会被删除
- key :objHero2.id
- value :objHero2
Demo:对key的弱引用
function createWeakTable(mode,tb)
tb = tb or {}
setmetatable( tb, { __mode = mode })
return tb
end
function printName(tb)
for k,obj in pairs(tb) do
print(k.name)
end
print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
end
objMapMem = createWeakTable( 'k' ) -- createWeakTable创建了一张弱表objMapMem
---------- 把所有玩家放到弱表 objMapMem里面
--objMapMem = { [ nAccountId ] = objHero, } -- 地图玩家 objMapMem 是一张表
local objHero1 = { id = 1, name = "obj1" }
local objHero2 = { id = 2, name = "obj2" }
local hero = objHero1 -- 对objHero1引用
objMapMem[ objHero1 ] = 1
objMapMem[ objHero2 ] = 2
---------- 遍历objMapMem打印所有玩家的名字
printName( objMapMem )
---------- 取消{ id = 1, name = "obj1" } 的objHero1引用
objHero1 = nil
collectgarbage()
printName( objMapMem )
---------- 取消{ id = 1, name = "obj1" } 的所有引用
objHero1 = nil
hero = nil
collectgarbage()
printName( objMapMem )
程序执行的结果:
obj1
obj2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
obj1
obj2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
obj2
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
objMapMem[ objHero2 ] = 1
- 这样创建的objMapMem是张弱表, 其他地方对key的引用取消了 , 这个objMapMem的字段也会被删除
- key :objHero2
- value :1