面向对象的lua类泄漏

时间:2012-07-14 22:26:24

标签: lua

我已经阅读了很多关于面向对象的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

中的setter写信给我
function component:addClickHandler(handler)
    table.insert(self.clickCallback, handler)
end

但是当我在一个组件上调用click(x,y)时,它会调用所有clickHandler,无论是另一个按钮还是标签。

正如您在上面所看到的,我正在设置一个名为focus的参数,这似乎遇到了同样的问题,其中为一个组件设置它(因为您可以看到我循环遍历每个组件)将其设置为all(所以如果我有4个组件,焦点会在每个组件上重置4次)

为什么lua这样做,以及可以做些什么来解决它?

1 个答案:

答案 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会调用ab的处理程序,因为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