lua 热更新原理(一)

热更一般是针对模块的线上替换。我们动态加载要热更的模块试试。例如,我们在循环间隔加载某模块,这样就能有时间去更改模块了。测试的代码如下:

for i = 1, 5 do
    local m = require('other')
    print('other.a is ', m.a)
    Sleep(5)
end
我们循环加载了other这个模块他仅仅返回一个local table {a = 100},在sleep(lua没有直接提供sleep,我们可以利用os模块自己实现)期间我们改变other模块a的值为101,不出意外,m.a还是100。这是为什么呢?

这是由于require缓存机制决定的,请参考lua require机制

要想打破require缓存机制,我们必须删除缓存,package.loaded[module_name] = nil就可以做到。

我们将package.loaded['other'] = nil加在第四行后,再改变a的值,不出意外,a的值被改变了。

还有一个问题就是,之前的旧数据可能被其他变量引用,所以旧数据仍然有可能存在,例如下面的代码:

local g = {}

for i = 1, 5 do
    local m = require('other')
    if (i == 1) then g = m end
    print('other.a is ', m.a)
    Sleep(5)
    package.loaded['other'] = nil
end
由于g第一次引用的是旧数据,最后打印g.a时还是100,而不是修改之后的值。我们画个示意图就能很好的说明问题:

左边是lua全局表package.loaded,require模块就会填入其中。再次require时我们发现他已经指向另一个表了,而g仍然指向之前的表数据。

怎么才能让g指向新的表数据,直接让g指向他不行吗?不太可行,因为在实际的项目中不太确定有哪些变量引用到了旧的数据,就算知道,那也是侵入式的修改了。另一种方法就是package.loaded仍引用旧的数据表,只不过与新的数据表交换数据。还是画个示意图:

有了上面的描述,相信代码实现很简单:

function reload_module(module_name)
    local old_module = package.loaded[module_name] or {}
    package.loaded[module_name] = nil
    require (module_name)

    local new_module = package.loaded[module_name]
    for k, v in pairs(new_module) do
        old_module[k] = v
    end

    package.loaded[module_name] = old_module
    return old_module
end
以上有个问题就是模块返回的最好是表数据,这样才能替换已经引用到的旧数据,例如g。

还有,如果要热更的模块中有全局变量,热更模块时修改了全局变量,那么在_G['other']指向的值也会被覆盖,这没什么问题,本来全局变量就应该被覆盖才对。但是在热更之前如果有变量指向这个全局变量就糟糕了,这个变量也应该被修改才对。所以类似上面的交换新旧package.loaded['other']数据,全局数据也应该交换才对。可惜的是,没有办法知道全局变量来自哪个模块,所以无法做到替换该模块的全局变量。不知道大佬们有没有办法
--------------------- 
作者:Shonm 
来源:CSDN 
原文:https://blog.csdn.net/zxm342698145/article/details/80613429 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
 本套课程分为基础与中级两部分,分别就lua语言的各方面知识点进行探讨,学习完本套课程,对于后续Xlua(Tolua等框架)技术的学习提供强大的语言技术保证。       本套lua课程采用入门与商业级两种开发IDE进行教学:入门级的SciTE内置IDE与商业级的IDEA lua插件。本套课程学习完毕,对于除了传统手游外,在VR、AR、商业级大型应用程序、嵌入式设备开发等领域都有较强的指导作用。           《lua中级篇》分为:“函数的进阶”、“字符串进阶”、“Table进阶”、“元表”、“OOP面向对象”、“协同程序”、“IO操作”、“调试与运行”等八个大的章节,详细深入讲解lua开发的方方面面。        内容包含lua可变参数、闭包、模块、函数尾调用、字符串模式匹配、字符串不变性原理、矩阵、链表、元表详解与应用、协同的生命周期与生产消费者问题、lua文件各种读写操作、lua执行外部代码与错误异常处理垃圾收集机制等。       最后,lua中级篇的学习,对于广大学员开发商业级lua热更新技术,具有不可替代的重要作用! 热更新系列(技术含量:中高级):B:《热更新框架设计之Xlua基础视频课程》https://edu.csdn.net/course/detail/27110C:《热更新框架设计之流程与补丁技术》https://edu.csdn.net/course/detail/27118D:《热更新框架设计之客户端框架(上)》https://edu.csdn.net/course/detail/27132E:《热更新框架设计之客户端框架(中)》https://edu.csdn.net/course/detail/27135F:《热更新框架设计之客户端框架(下)》https://edu.csdn.net/course/detail/27136 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值