上回提到元表优化 Lua 配置文件,以减少重复字段,节省内存开销。

除了这种直接地减少内存开销的方法,使用元表还能实现数据的延迟加载,从另一个角度节约内存。

延迟加载

-- PropModel.lua
PropModel = {
    [1001] = {
        ID   = 1001,
        name = "道具1001",
        desc = "道具1001描述",
        ...
    },
    [1002] = {
        ID   = 1002,
        name = "道具1002",
        desc = "道具1002描述",
        ...
    },
    ...
}

上面依然是最常见的道具表,所有道具都配置在同一个表中,初始化时会全部加载进内存。 然而大多数道具是玩家并不拥有的,在内存中长期停留浪费空间。

通过使用元表,我们能做到每个道具按需(延迟)加载。

  1. 首先清空表数据,使用元表的__index方法实现延迟加载:

    -- PropModel.lua
    PropModel = {} -- 道具表不再直接存放数据
    
    -- 使用元表延迟加载数据
    setmetatable(PropModel, {
        __index = function(t, k)
            local item = require(string.format("PropModel_%s", k))
            PropModel[k] = item
            return item
        end,
    })

  2. 将各道具数据另外存放——将道具1001单独存放:

    -- PropModel_1001.lua
    local PropModel_1001 = {
        ID   = 1001,
        name = "道具1001",
        desc = "道具1002描述",
        ...
    }
    return PropModel_1001

最后

上面的代码是每个item单独拆分到一个文件中。 如果有必要,也可以按照ID进行区间拆分,将多个item放在一个文件中。 在__index方法中判断ID落在哪个区间,将该区间数据全部加载。

同时,拆分后的数据依然可以结合上一篇 的“默认字段”的方法使用。