Lua实现KVO

Lua元表使用 __index和__newindex方法有点类似get和set方法,可以利用这个特性实现监听table的属性变化。

  • table.key = value 只有在table中不存在该key时才会走元表的__newindex方法。
    可以对 Lua实现继承 中的Object做一层封装,返回一个空表,外界对这个空表的所有访问和设置都要通过元表的__index和__newindex方法,从而实现监听。
local Observable = Object:extend()

function Observable:new()
    Observable.super.new(self)
    return self:_observable()
end

function Observable:_observable()
    self.observKeys = {}
    self.__observable_table = setmetatable({}, {
        __index = self,
        __newindex = function(t, k, v)
            print("VALUE CHANGE~ "..k.."=== old(",self[k],") new(",v,")")
            
            local callback = self.observKeys[k]
            if type(callback) == "function" then
                callback(self[k], v)
            end
            
            self[k] = v
        end,
        __pairs = function (t) return pairs(self) end,
        __ipairs = function (t) return ipairs(self) end,
        __len = function (t) return #self end
    })

    return self.__observable_table
end

local a = Observable:new()
a.v2 = {}           -- VALUE CHANGE~ V2 === old( nil ) new( table:0x281ab19c0 )
a.v2 = "123"        -- VALUE CHANGE~ V2 === old( table:0x281ab19c0 ) new( 123 )

ps. 这里在new方法里返回了一个空表,用Observable:new()创建 而没有用__call,也可以将__call改造成new方法返回实例对象。

你可能感兴趣的:(Lua实现KVO)