关于handle重用的问题

所有地图上存在的 单位、物品、单位组、点、触发器、特效等等 都是 handle。

handle可以理解为魔兽各种数据(单位、物品等)内存地址的索引。

并且魔兽在handle移除后 会重新分配该handle 给后面创建的数据(单位、物品、触发器、特效等等)

handle重用现象举列:

  1. 地图存在一个 单位变量 u = 单位handle(值为123456789。注意单位handle只是人为主观的区别,本质都是handle,一个整数而已)
  2. 调用RemoveUnit 移除上述handle
  3. 新建一个物品
  4. 杀死单位变量 u
  5. 可能的结果: 你在第3步创建的物品被杀死了(或出现任何意外结果)

避免handle重用造成的影响

  1. 延迟(计时器执行)使用handle变量时请在handle变量赋值时使用handle_ref增加引用计数。待延迟使用变量后使用handle_unref减少引用计数,以确保在此期间handle没有被新数据顶用的可能

  2. 对所有数据(单位、物品等)执行操作前 在一个触发里执行获得并操作,如选取为单位组 立即遍历单位组执行操作。(确保获得的handle就是自己想要的数据(单位、物品等)的handle)

    错误示例: 选取为单位组 保存到一个变量 再在其他触发里遍历单位组 (除非你能保证全局游戏中没有触发会在期间移除此单位组中的单位)

    (如果在选取和遍历的期间。单位组被任何其他触发使用RemoveUnit删除了单位。那么后面遍历单位组时,遍历的单位可能是其他任意数据(其他单位、物品、特效等等))

  3. 对所有变量执行操作前 确保变量是否已过时? (确保在获得变量与操作变量的期间 变量未被移除handle)

  4. 对全局变量操作时 一定要确保全局变量不被删除 或删除后,需马上设置null。否则其他触发使用时就会获得其他游戏数据(其他单位、其他物品、其他特效等等)(出现灵异情况)

一些常见错误示例

1、 练功房系统 每次刷兵记录到一个lian_gong_guai变量里。 然后单位死亡时做RemoveUnit 移除单位排泄处理。

当离开练功房 遍历lian_gong_guai以删除练功房的怪物 (注意此操作会由于 最后一波怪死掉的部分已被移除了。由于handle重用的特性。导致会删除其他新创建的数据(单位、物品、特性等等))

正确方式: 当离开练功房 遍历lian_gong_guai以删除练功房的怪物 改为选取练功房内的怪物 然后执行删除。lian_gong_guai除了在刷兵时有用 之后都是过时的变量了,里面的handle指向的数据可能已不是练功房的单位了

2、 释放技能给敌人施加一个7秒的debuff 每秒扣100生命值。如果在代码里只是第一次选取技能释放的敌人 并保存到变量中,每隔1秒去伤害敌人。那么可能敌人中途死亡会导致新创建的单位和物品等顶上这个handle。 会导致对其他单位、物品造成伤害或杀死了物品。需使用handle_ref在初始设置变量时引用住敌人的handle 然后debuff结束时在使用handle_unref释放单位的handle。以确保在此段时间内handle未被重用!

扩展阅读

以上问题 在t作图与jass作图 不会很严重无需特意考虑。 Handle有引用保护。 你的全局一直引用 那这个handle就会一直不释放 在Jass那边local需要null的原因,就是要释放这个引用

在lua与ts作图时 未指定handle引用数时(目前默认为lua引擎不会增加和减少handle引用数). handle重用的情况会很严重。