如何防止添加到 List 的类的实例在 IEnumerator 方法中被销毁

本文关键字:方法 IEnumerator 实例 添加 何防止 List | 更新日期: 2023-09-27 18:36:36

如果您能帮助我解决这个问题,我将不胜感激。

RivalItem 类的字段应该用 collectItems 中的数据填充。

我们对手的物品将列在对手列表中,其数据来自传入数据。因为我不知道什么时候开始协程结束收集数据方法设置进度栏和更新检查对手列表的元素。

不幸的是,在方法中实例化的 RivalItem 对象消失了,因此列表为空。

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
public class OpponentItem {
    public int item_id ;
    public string item_type;
    public string item_name;
    public int item_star; 
    public int item_bonus;
    public OpponentItem() : base(){
    }
}
public class TestBug : MonoBehaviour {
    public List<OpponentItem> opponentList;
    private float barValue;
    public bool isDone;
    public static string[] collectItems =  new string[5]{
        "item_id=12",
        "item_type=Weapon",
        "item_name=Sword",
        "item_star=2",
        "item_bonus=10",
    };
    public string[] incomingData;
    public float progressBar {
        get{ 
            return barValue;
        }
        set{
            barValue = value;
            isDone = true;
        }
    }
    void Start () {
        isDone = false;
        string joined = System.String.Join("|", collectItems);
        incomingData = new string[5];
        incomingData[0] = joined;
        incomingData[1] = joined;
        incomingData[2] = joined;
        incomingData[3] = joined;
        incomingData[4] = joined;
        opponentList = new List<OpponentItem>();
        StartCoroutine(collectData<OpponentItem>(opponentList, incomingData, collectItems));
    }
    void Update(){
        if (isDone){
            isDone = false;
            Debug.Log(opponentList[1].item_id);
        }
    }
    public IEnumerator collectData<T>(List<T> list, string[] tempArray, string[] queryArray) where T : new() {
        list =  new List<T>(tempArray.Length);
        for(int h = 0; h < tempArray.Length ; h++){
            list.Add(new T()); 
            string[] mybox = new string[queryArray.Length]; 
            mybox = tempArray[h].Split('|');
            for (int k = 0; k < queryArray.Length ; k++){
                string[] inbox = new string[2];
                inbox = mybox[k].Split('=');
                if (list[h].GetType().GetField(inbox[0]).FieldType.FullName == "System.Int32"){
                    list[h].GetType().GetField(inbox[0]).SetValue(list[h], Int32.Parse(inbox[1]));
                    Debug.Log(list[h].GetType().GetField(inbox[0]).GetValue(list[h]));
                }
                else if(list[h].GetType().GetField(inbox[0]).FieldType.FullName == "System.Single"){
                    list[h].GetType().GetField(inbox[0]).SetValue(list[h], Single.Parse(inbox[1]));
                    Debug.Log(list[h].GetType().GetField(inbox[0]).GetValue(list[h]));
                }
                else{
                    list[h].GetType().GetField(inbox[0]).SetValue(list[h], inbox[1]);
                    Debug.Log(list[h].GetType().GetField(inbox[0]).GetValue(list[h]));
                }
            }
        }
        yield return new WaitForSeconds(0.2f);
        progressBar += 0.5f; 
    }

}

如何防止添加到 List 的类的实例在 IEnumerator 方法中被销毁

这里有

一个问题。 您的列表将始终为空,因为默认情况下参数是按值传递的(请参阅此 MSDN 链接)

opponentList = new List<OpponentItem>();        
StartCoroutine(collectData<OpponentItem>(opponentList, incomingData, collectItems));

分配list = new List<T>(tempArray.Length)后,将项目添加到新的列表引用中,但不添加到传递给 collectData() 的引用中

您有 2 个选项:

1) 清除列表而不是重新分配

 public IEnumerator collectData<T>(List<T> list, string[] tempArray, string[] queryArray) where T : new() {
    // list =  new List<T>(tempArray.Length); // ** problem
    list.Clear();  // ** try clearing the list instead
    for(int h = 0; h < tempArray.Length ; h++){

2) 通过引用传递列表

 opponentList = new List<OpponentItem>();
 StartCoroutine(collectData<OpponentItem>(ref opponentList, incomingData, collectItems));
}
    public IEnumerator collectData<T>(ref List<T> list, string[] tempArray, string[] queryArray) where T : new() {
    list =  new List<T>(tempArray.Length);