删除列表最后元素触发Argument Out Of Range Exception的问题排查
问题分析与解决方案
核心问题1:删除最后一个选中元素后的参数越界
删除最后一个选中元素后,previousID仍保留着旧列表的最后一个索引(比如原列表有N个元素,索引为N-1),但新的prefabList长度变为N-1,最大有效索引是N-2。此时直接用旧索引访问列表就会触发数组越界异常。
核心问题2:修复越界后ID与previousID停止更新的原因
你最后一次修改的代码中,删除最后一个元素后:
JLID仍保留旧的无效索引,新列表的长度小于该索引值- 因
ID < prefabList.Count条件不满足,else if分支无法执行,既不能更新颜色,也无法修改previousID Update方法持续传入旧的JLID,而新生成的按钮未被点击,导致JLID始终无法更新
代码修复步骤
1. 修正GenerateOptions方法的错误
原方法在foreach循环内重复执行prefabList.Clear(),会导致列表提前清空且遍历修改集合引发异常,需将清空操作移到循环外:
private void GenerateOptions() { // 先清空列表,再销毁子物体 prefabList.Clear(); foreach (Transform child in ScrollViewContent.transform) { Destroy(child.gameObject); } for (int i = 0; i < JLList.Count; i++) { GameObject newJLOption = Instantiate(ButtonPrefab, PrefabParent.transform); int JLIndex = i; newJLOption.GetComponent<Button>().onClick.AddListener(() => LoadJL(JLIndex)); prefabList.Add(newJLOption); } // 列表更新后重置选中状态 ResetSelectedState(); }
2. 添加重置选中状态的方法
列表元素变化后,必须重置选中索引,避免使用无效值:
private void ResetSelectedState() { JLID = -1; // 标记为无选中状态 SetEditorJL.previousID = -1; // 可选:新列表不为空时默认选中第一个元素 if (prefabList.Count > 0) { JLID = 0; SetEditorJL.SetUnderEditJudgeLineColor(prefabList, JLID); } }
3. 完善颜色设置方法的边界检查
确保所有索引访问都在有效范围内,同时处理无选中状态的情况:
public void SetUnderEditJudgeLineColor(List<GameObject> prefabList, int ID) { // 索引无效或列表为空时直接返回 if (prefabList.Count == 0 || ID < 0 || ID >= prefabList.Count) { return; } // 重置之前选中的元素颜色(如果索引有效) if (previousID != -1 && previousID < prefabList.Count && previousID != ID) { prefabList[previousID].GetComponent<Image>().color = Color.white; } // 设置当前选中元素的颜色并更新previousID prefabList[ID].GetComponent<Image>().color = Color.yellow; previousID = ID; }
4. 优化Update方法的调用逻辑
避免无意义的重复调用,仅在JLID有效且变化时执行颜色设置:
private int lastJLID = -1; private void Update() { JLList = MenuManager.GetComponent<AddJL>().JLList; CheckForChange(); // 仅当JLID有效且发生变化时调用颜色设置 if (JLID != lastJLID && JLID >= 0 && JLID < prefabList.Count) { SetEditorJL.SetUnderEditJudgeLineColor(prefabList, JLID); lastJLID = JLID; } }
关键说明
- 列表元素增删后必须重置选中状态,彻底避免无效索引的使用
- 所有索引访问前必须严格检查
0 <= index < list.Count的边界条件 - 减少Update中的冗余调用,既能避免逻辑异常,也能降低性能消耗
内容的提问来源于stack exchange,提问作者user19518133
相关产品推荐
相关产品推荐

