1

很久以前我写了一个对象池系统(嗯,大部分是我当时需要的部分)。现在程序已经在它上面进化了,我发现了一个我认为我在实现池时没有的缺陷。

本质上,池将一个对象作为构造函数,并使用反射克隆它以创建该对象的数组。这是在池中创建对象的函数的实现:

        poolSize i = 0;
        T[] oldData = null;

        if (this.chunks != null && this.chunks.Length > 0)
        {
            oldData = new T[this.depth];
            Array.Copy(this.chunks, oldData, this.chunks.Length);
        }

        this.chunks = new T[this.depth + this.depthIncrement];

        if (oldData != null)
        {
            Array.Copy(oldData, this.chunks, oldData.Length);
        }

        for (i = this.depth; i < this.depth + this.depthIncrement; i++)
        {

            this.chunks[i] = Cloner.CloneObjectWithIL(this._template);
            this.freeQueue.Add(i);
        }

        this.depth += this.depthIncrement;

现在,检查 Object.ReferenceEquals(pool.chunks[0], pool.chunks[1]) 返回 false - 所以看起来数组的每个索引都是它自己的对象,而不仅仅是对一个对象的一堆引用。

现在在主代码中,我们使用 GetObject 方法从池中获取一个对象:

    public T GetObject(T tmp)
    {
        T retObj = tmp;

        this.chunks[this.volume] = retObj;
        this.usedQueue.Add(this.volume);
        this.volume++;

        return retObj;
    }

我遇到了一些受保护的内存错误(C# 相当于 SEGFAULT?)所以我继续进行一些调试。所以我使用了我通常不会做的代码,因为它违背了池背后的一些目的:

Map.Entity tmp = Map.Entity.EntityPool.chunks[0];
tmp.SetPosition(m, 1, 9);

现在,当我在那之后添加一个断点并查看块数组时,块数组的每个元素的位置都是 (1, 9),而除了索引 0 之外,它们都应该是 (0, 0)。

我在这里想念什么?

4

0 回答 0