Lua弱表

Lua弱表

类型和引用类型

  • Lua有8种基本类型:nil、boolean、number、string、function、userdata、thread、table
  • 对象object:Tables、functins、threads、userdata, 其变量为引用类型
  • 引用类型:赋值、参数传递、函数返回等都操作的是这些值的引用,并不产生任何copy行为
  • nil的主要用途就是一个所有类型之外的类型,用于区别其他7中基本类型

垃圾回收机制

  1. gc自动运行,也可以手动调用
  2. 自动收集的目标是引用计数为0的对象
  3. 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值