public List<Plate> plateList = new List<Plate>(); 我创建一个 list 然后在update 里面不停的 插入和遍历数据,然后同时 不停的删除数据, 插入和删除的 速度不同, 这时候就会偶尔出现ArgumentOutOfRangeException: Argument is out of range.Parameter name: index 报错提示, 我的遍历方式是
for (int i = 0; i < plateList.Count; i++)
{
float dis = Vector2.Distance(plateList[i].pos, pos);
if (dis <= posDistance)
{
return;
}
}
我理解是 在某一帧 遍历 时候, 恰好 plateList[i] 被删除了。 所有就出现报错 , 哪位大佬说下 如何才能避免出错呀。 或者有什么好的方式 ,可以同时对一个链表 进行 插入,删除 和遍历操作。
两个方法粗略的写一下哈~~
方法1>
void update()
{
new 新列表 deleList;
for(你原本列表)
{
if(执行条件满足)
执行你的正经事情
if(删除条件满足)
deleList.add(条目);
}
for(便利deleList)
{
原列表.remove(条目)
}
}
你看这样子,会产生越界吗?不会的~~
方法2> 利用MonoBehaviour生命周期 update 跟 lateupdate 执行差(非时间差哦,这仍然是同一帧)
void update()
{
for(你原本列表)
{
if(执行条件满足)
执行你的正经事情
}
}
void lateupdate ()
{
for(你原本列表)
{
if(删除条件满足)
原列表.remove(条目)
}
}
总结一下:方法1,利用临时列表暂时存储需要删除的条目,在执行正常循环完毕后,从原本列表内删除存储的条目,这样避免越界的
方法2,利用MonoBehaviour生命周期 update 跟 lateupdate 执行差,两个update 内各自执行一套相互不影响的循环,并执行将删除操作分割,这种方法也能避免越界~
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 1s添加一个元素,2s删除一个小于50的元素
/// </summary>
public class ListInsertAndRemove : MonoBehaviour
{
//private float firstInterval = 0f;
//private float secondInterval = 0f;
public static int ComPareNum = 50;
[SerializeField]
private List<int> m_IntList = new List<int>();
private List<int> m_tempList = new List<int>();
// Use this for initialization
void Start()
{
for (int i = 0; i < 50; i++)
{
int randNum = Random.Range(1, 100);
m_IntList.Add(randNum);
}
}
void Update()
{
m_tempList.Clear();
for (int i = 0; i < m_IntList.Count; i++)
{
if (m_IntList[i] % 2 != 0)
{
m_tempList.Add(m_IntList[i]);
}
}
for (int i = 0; i < m_tempList.Count; i++)
{
m_IntList.Remove(m_tempList[i]);
}
}
// Update is called once per frame
//void Update()
//{
// int randNum = Random.Range(1, 100);
// m_IntList.Add(randNum);
//}
//void LateUpdate()
//{
// for (int i = 0; i < m_IntList.Count; i++)
// {
// if (m_IntList[i] < ComPareNum)
// {
// m_IntList.RemoveAt(i);
// }
// }
//}
}