lua中handler方法的原理

对于quick中handler方法,以前虽然知道怎么去使用,但是它的原理一直没有弄清楚,所以一直都是一知半解的状态,今天在老大的指导下终于有所觉悟!发下帖子分享下喜悦。
如果要知道handler方法的原理首先得知道lua中 “.” 和 “:” 还有 "…"的用法,关于这些网上资料就多啦!都说得比较透彻,在这里就不罗嗦了。。。
不过为了说明还是首先贴一段测试
local cls = {}
function cls:fun()
self._m= “hello”
end
local clsb = {}
cls.fun(clsb)
print(clsb._m)
print(cls._m)
当执行完这一段代码后输出的结果为:
hello
nil
看出来什么问题没?是的cls中的self变成了clsb,所以当使用cls.fun调用cls:fun时,cls.fun中的第一个参数就是cls:fun中的self。

源码:
function handler(obj, method)
returnfunction(…)
return method(obj,…)
end
end
由此不难发现handler通过接收的两个参数obj, method创建了一个匿名函数并将其返回,并且调用匿名函数时所传入的参数也将传入method方法中,作为obj后面的参数。

好吧我们看看它的用法:
既然通过handler封装返回的是一个匿名函数,所以可以这样调用
localcls = {}
cls._m = “close”
function cls:onClose()
print(self._m)
end
handler(cls,cls.onClose)()
结果为:
close
此时我们通过handler将cls作为cls.onClose的第一个参数传入,此时执行返回的匿名函数时则等价于cls.onClose(cls)由于传入的参数就是其本身所以self就是cls也即等价于cls:onClose(),所以此代码段打印出close。
如果第一个参数不是它自己的话由上面的测试代码可以知道那样就不会是我们想要的结果了,我就不试了不信你试试…

简单的调用会了,我们再来看一看它更复杂的用法
handler(“hello”,handler(cls,cls.onClose))(“world”)
这个明白是什么东西吗?好吧我看了也是一头雾水,不过我们也可以慢慢地去分析,逐渐就会明了了
此时我们把handler(cls,cls.onClose)看成是method,则上面的代码可以转换成
handler(“hello”,method)(“world”)
此时通过传入参数”world”调用handler返回的匿名函数,实际调用的函数method的第一个参数为”hello”,所以它的调用可以简化为
method(“hello”,”world”)
此时我们再将method展开
handler(cls,cls.onClose) (“hello”,”world”)
同理展开为
cls.onClose(cls,”hello”,”world”)
同理那一长串调用的就是
cls:onClose(“hello”,”world”)

理论结合实践,那我们就来检验一下:
local cls = {}
function cls:onClose(…)
print(…)
end
handler(“hello”,handler(cls,cls.onClose))(“world”)
结果为:
hello world
多么亲切的hello world呀!

:2: 顶!!!!!!!!!!!!!!!!!!!

:2: :2: :2: :2:

楼主,请教个问题。在cocos code ide或者用quick cocos建立的自带的小游戏里,
GameView.lua文件里有这么一段:

function GameView:start()
    self:scheduleUpdate(handler(self, self.step))
    return self
end

function GameView:step(dt)
    if self.lives_ <= 0 then return end

    self.addBugInterval_ = self.addBugInterval_ - dt
    if self.addBugInterval_ <= 0 then
        self.addBugInterval_ = math.random(GameView.ADD_BUG_INTERVAL_MIN, GameView.ADD_BUG_INTERVAL_MAX)
        self:addBug()
    end

    for _, bug in pairs(self.bugs_) do
        bug:step(dt)
        if bug:getModel():getDist() <= 0 then
            self:bugEnterHole(bug)
        end
    end

    return self
end


```


这里的step 函数参数dt就没有初始化和传入一个参数。那么dt的值哪里来的啊?

这是一个典型的闭包啊, 不过quick里可以封的更好一些, 比如handler应该支持可变参数列表

嗯,好滴。不过我是初学这个。
上边那个问题和这个差不多,不过这个函数所需要的就是event事件,是不是都是在c++的实现里指定传入什么值的么?
因为我看了handler方法,没有写参数为空的时候,怎么给调用的方法传参数啊。

– add touch layer
display.newLayer()
:onTouch(handler(self, self.onTouch))
:addTo(self)

function GameView:onTouch(event)
if event.name ~= “began” then return end
local x, y = event.x, event.y
for , bug in pairs(self.bugs) do
if bug:getModel():checkTouch(x, y) then
self:bugDead(bug)
end
end
end

看不懂你写的什么,这代码能运行吗, 哪来的onTouch方法

dt 就是上一帧和这一帧所经历的时间,单位是秒,是 delta time 的简写。

我也没怎么看明白他要问什么,不过onTouch方法在quick3.3中是有的,在shortcodes文件内

这个ontouch方法是我用3.4建立的api自带的游戏里一个场景这么写,正如楼上的大哥说的,3.3可能也有,这个就没去研究过了。
不过我疑问的是,handler方法没有传参数给下边的onTouch,onTouch的参数(event)不需要传入的话,它的值是怎么被指定的?

这是一个回调函数,相当于先向系统注册一个函数指针,当运算结果出来后再把结果通过参数传给这个函数调用,大概就这么个概念吧