Open w4454962 opened 4 years ago
不要异步创建table
异步的原因是 你 初始化给每个object 一个gchash 然后pairs 时加入到哈希算法里 一旦gchash出现异步 接下来 再new 的对象 就会出现不一样的gchash 在pairs 时 就会乱序了 你为了保证hash函数的随机性 导致的。
这个不可能 那string呢。 只要异步string gchash同样会异步
string没有gchash
在魔兽里 避免异步table 比 避免pairs更难。
其实把 根据gchash 加入哈希算法 改成 根据gchash 遍历 就可以避免掉table 遍历异步的问题 只是损失的是那点不可靠的随机性
这个解决方案和不用pairs或者自己实现pairs等价
研读了一下源码, 发现重写pairs是简单的, 但是重写next 相对困难许多, pairs异步的地方正是在于next 只重写pairs并不彻底。
我想到了一个解决方案 在魔兽中 异步创建table 有2种可能
1 在异步回调的函数里 这个几乎可以无视
2 是在本地玩家的if里
主要解决的是在 本地玩家if 里的问题 那么很显然 只要gchash 关联lua栈 例如 下面伪代码 function test() local gchash = 1000 local t = {gchash = gchash} gchash = gchash + 1
if 玩家 == 本地玩家 then
local gchash = 2000
local t = {gchash = gchash}
gchash = gchash + 1
local t2 = {gchash = gchash}
gchash = gchash + 1
end
local t2 = {gchash = gchash}
gchash = gchash + 1
local map = {}
map[t] = 1
map[t2] = 2
for tbl, num in pairs(map) do --此时 if中异步创建的table 不会影响到其他地方。
print(tbl, num)
end
end
那么要解决的是 在lua申请栈空间的时候 多申请一个int 记录一个 不会冲突的数字, 然后创建table时取该数字不断+1 即可。
重现代码如下 打出来的日志 根本不一致
jass.TimerStart(jass.CreateTimer(), 0.1, true, function () local map = {} for i = 1, 100 do local object = { id = i, } map[object] = math.random(1, 10000) end
end)
掉线日志以及地图.zip
从前就一直怀疑你修复的有问题 今天测了一下 发现是真的有问题 被我逮到了吧