Lua中AppendScript函数优化:避免事件触发时重复追加方法
解决AppendScript重复追加方法的问题
要避免同一个方法被重复追加到UI控件的事件handler中,核心思路是给每个控件维护一个已注册方法的记录集合,每次追加前先检查该方法是否已经存在,存在则跳过追加逻辑。以下是具体实现方案:
方案1:基于函数本身去重(适合具名函数)
修改原有的AppendScript函数,给每个控件实例添加一个_registeredScripts表,用来记录每个事件handler下已添加的方法:
local mt = { AppendScript = function(self, handler, method) -- 初始化存储已注册方法的结构 self._registeredScripts = self._registeredScripts or {} self._registeredScripts[handler] = self._registeredScripts[handler] or {} -- 检查方法是否已存在,存在则直接返回 if self._registeredScripts[handler][method] then return end local func = self:GetScript(handler) -- 合并原有脚本与新方法 local newFunc if func then newFunc = function(...) func(...) method(...) -- 若不需要传递事件参数,可改为method(),与原逻辑一致 end else -- 原有脚本为空时,直接使用新方法 newFunc = method end self:SetScript(handler, newFunc) -- 标记该方法已注册 self._registeredScripts[handler][method] = true end, } setmetatable(object, { __index = setmetatable(mt, getmetatable(object)) })
关键点说明
_registeredScripts是控件实例独有的表,按事件handler分类存储已添加的方法,利用Lua中函数作为第一类值的特性,直接用method本身作为键来判断重复。- 仅当方法未注册时才执行追加逻辑,从根源避免重复绑定。
方案2:自定义唯一标识去重(适合匿名函数)
如果使用匿名函数(每次创建的匿名函数是不同的Lua值,无法用方案1去重),可以给每个待追加的方法指定一个唯一key,通过key来判断重复:
local mt = { AppendScript = function(self, handler, key, method) -- 兼容不传key的场景,默认用method本身当key if not method then method = key key = method end -- 初始化存储结构 self._registeredScripts = self._registeredScripts or {} self._registeredScripts[handler] = self._registeredScripts[handler] or {} -- 通过key检查是否已注册 if self._registeredScripts[handler][key] then return end local func = self:GetScript(handler) local newFunc = func and function(...) func(...) method(...) end or method self:SetScript(handler, newFunc) -- 标记该key对应的方法已注册 self._registeredScripts[handler][key] = true end, } setmetatable(object, { __index = setmetatable(mt, getmetatable(object)) })
使用示例
-- 用自定义字符串作为唯一key,绑定匿名函数 local method = function() -- do stuffs end object:AppendScript("OnShow", "MyUniqueOnShowHandler", method)
这样即使多次调用AppendScript传入相同的key,也只会绑定一次方法。
内容的提问来源于stack exchange,提问作者user3713179
相关产品推荐
相关产品推荐

