You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除列表最后元素触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:24:19