-- 闭包绑定
function Bind(self, func, ...)
assert(self == nil or type(self) == "table")
assert(func ~= nil and type(func) == "function")
local params = nil
if self == nil then
params = SafePack(...)
else
params = SafePack(self, ...)
end
return function(...)
local args = ConcatSafePack(params, SafePack(...))
func(SafeUnpack(args))
end
end
-- 回调绑定
-- 重载形式:
-- 1、成员函数、私有函数绑定:BindCallback(obj, callback, ...)
-- 2、闭包绑定:BindCallback(callback, ...)
function BindCallback(...)
local bindFunc = nil
local params = SafePack(...)
assert(params.n >= 1, "BindCallback : error params count!")
if type(params[1]) == "table" and type(params[2]) == "function" then
bindFunc = Bind(...)
elseif type(params[1]) == "function" then
bindFunc = Bind(nil, ...)
else
error("BindCallback : error params list!")
end
return bindFunc
end
比如我们有多个button需要注册click的回调函数,那么怎么区分回来的是哪个button呢?
我么可以继承Button函数,重写其OnPointerClick方法,在回调的时候将this传递过来:
--注册回调函数
self.loginBtnComp = self.loginBtn.gameObject:GetComponent(typeof(CS.PButton))
self.loginBtnComp:RegisterClickCallback(OnClickLoginButton)
function OnClickLoginButton(button)
print("click")
print(button)
end
另外一种方法,是使用闭包的方式:
self.loginBtnComp = self.loginBtn.gameObject:GetComponent(typeof(CS.PButton))
local callback = Bind(self, OnClickButton, self.loginBtnComp)
self.loginBtnComp:RegisterClick(callback)
local function OnClickButton(self, button)
print("click button")
end
这里的Bind就是生成一个闭包函数,使得回调来的时候,能记得之前的上下文中的参数params:
这样的好处是,我们不需要再继承一个Button了。
何时释放闭包:
参考:
https://www.cnblogs.com/unityzc/p/10317129.html
如果在lua中保存了闭包,则要在lua中进行赋值为nil。
如是临时local的,注册到C#中了,那么要销毁的时候,要将C#中的回调函数赋值为null。
local callback = Bind(self, OnClickButton, self.loginBtnComp)
self.loginBtnComp:RegisterClick(nil)