我已经阅读了很多关于面向对象的lua(设置metatable),我构建了一个完整的继承系统。
我现在的问题是,有些变量似乎互相泄漏了。如果我调用一个名为window:click(x, y)
的函数,函数调用就好了。这个函数的工作是通知我点击的所有组件。它正在做什么
for number, component in pairs(self.components) do
component.focus = false
component:click(x, y, msg)
end
self.components
包含窗口的所有组件
要充当所有组件的基类,我有一个名为component.lua的类,此文件创建一个名为components的表,并向其添加create()
方法(执行所有常用的OO lua内容) ,这个基类包含我在所有组件中想要的所有方法和变量,包括component:click(x, y)
,再一次,它被调用。
for key, callback in pairs(self.clickCallback) do
callback()
end
return
clickCallback
表包含在通知组件时应调用的函数。并在component.lua
从这里开始,我将这个类继承到我的其他类,只需设置我的新组件(文本框,按钮,标签等)的元表。这些组件被添加到窗口中的self.components
表中。
问题是这些组件中的每一个都应该有自己的clickCallback表。我通过component.lua
function component:addClickHandler(handler)
table.insert(self.clickCallback, handler)
end
但是当我在一个组件上调用click(x,y)
时,它会调用所有clickHandler,无论是另一个按钮还是标签。
正如您在上面所看到的,我正在设置一个名为focus
的参数,这似乎遇到了同样的问题,其中为一个组件设置它(因为您可以看到我循环遍历每个组件)将其设置为all(所以如果我有4个组件,焦点会在每个组件上重置4次)
为什么lua这样做,以及可以做些什么来解决它?
答案 0 :(得分:2)
首先,如果您刚刚发布了一个完整的工作示例来证明问题,那么尝试弄清楚您的小片段会发生什么变得非常困难。
self.components包含窗口的所有组件
这可能是你的问题。再次,这是猜测,因为您没有显示create
方法,但如果您的构造函数没有为每个实例初始化clickCallback
成员,那么它将会使用类本身的表。
以下是一个说明问题的示例:
component = {}
component.__index = component
component.clickCallback = {}
function component.create()
return setmetatable({}, component)
end
function component:addClickHandler(handler)
table.insert(self.clickCallback, handler)
end
function component:click(x,y)
for _,callback in pairs(self.clickCallback) do
callback(x,y)
end
end
a = component.create()
b = component.create()
a:addClickHandler(function(x,y) print("a", x, y) end)
b:addClickHandler(function(x,y) print("b", x, y) end)
a:click(10,20)
b:click(11,22)
这是输出,显示您描述的症状:
a 10 20
b 10 20
a 11 22
b 11 22
换句话说,调用a:click
会调用a
和b
的处理程序,因为clickCallback
表在类本身中,由所有实例共享类。修复它确保每个实例都有自己的处理程序表:
component = {}
component.__index = component
function component.create()
return setmetatable({ clickCallback = {}}, component)
end
function component:addClickHandler(handler)
table.insert(self.clickCallback, handler)
end
function component:click(x,y)
for _,callback in pairs(self.clickCallback) do
callback(x,y)
end
end
a = component.create()
b = component.create()
a:addClickHandler(function(x,y) print("a", x, y) end)
b:addClickHandler(function(x,y) print("b", x, y) end)
a:click(10,20)
b:click(11,22)
输出:
a 10 20
b 11 22