找回密码
 注册帐号

扫一扫,访问微社区

GUI 如果 对一个链表同时做 插入和删除操作

24
回复
1495
查看
[ 复制链接 ]
6蛮牛粉丝
1330/1500
排名
3221
昨日变化

48

主题

426

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
149133
好友
20
蛮牛币
1101
威望
0
注册时间
2016-5-19
在线时间
392 小时
最后登录
2019-4-23
2018-11-5 15:01:45 显示全部楼层 阅读模式
10蛮牛币
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] 被删除了。 所有就出现报错 ,   哪位大佬说下 如何才能避免出错呀。 或者有什么好的方式 ,可以同时对一个链表 进行  插入,删除 和遍历操作。

回复

使用道具 举报

排名
673
昨日变化

19

主题

1181

帖子

3548

积分

Rank: 9Rank: 9Rank: 9

UID
68430
好友
13
蛮牛币
18345
威望
0
注册时间
2015-1-14
在线时间
970 小时
最后登录
2019-4-24
2018-11-5 15:01:46 显示全部楼层
两个方法粗略的写一下哈~~
方法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 内各自执行一套相互不影响的循环,并执行将删除操作分割,这种方法也能避免越界~


希望能帮到你


点评

很强,赞!  发表于 2018-11-6 15:56
回复

使用道具 举报

5熟悉之中
721/1000
排名
4111
昨日变化

0

主题

37

帖子

721

积分

Rank: 5Rank: 5

UID
252114
好友
0
蛮牛币
569
威望
0
注册时间
2017-11-2
在线时间
314 小时
最后登录
2019-4-11
2018-11-5 15:55:29 显示全部楼层
遍历数组前,拿一个新列表用来遍历,遍历后更新这个新列表。保证此次遍历时列表长度不会有变化。或者写一个遍历方法,一个列表一旦开始遍历就不执行删除增加的操作,遍历完后调用删除增加的方法更新列表
回复

使用道具 举报

6蛮牛粉丝
1333/1500
排名
3110
昨日变化

5

主题

361

帖子

1333

积分

Rank: 6Rank: 6Rank: 6

UID
234410
好友
2
蛮牛币
1507
威望
0
注册时间
2017-7-26
在线时间
477 小时
最后登录
2019-4-24
2018-11-5 16:19:37 显示全部楼层
如果单纯的只是为了防止被删除影响数目 何不这样
int len = plateList.Count;
for (int i = 0; i < len ; i++)
回复

使用道具 举报

2初来乍到
137/150
排名
16593
昨日变化

0

主题

25

帖子

137

积分

Rank: 2Rank: 2

UID
143473
好友
0
蛮牛币
241
威望
0
注册时间
2016-3-25
在线时间
52 小时
最后登录
2019-2-14
2018-11-5 16:51:51 显示全部楼层
方法一:利用Unity脚本的生病周期进行List的增删遍历
方法二:遍历的时候判断一下当前i是否大于等于List的count,是return或break,否就继续;
回复

使用道具 举报

6蛮牛粉丝
1330/1500
排名
3221
昨日变化

48

主题

426

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
149133
好友
20
蛮牛币
1101
威望
0
注册时间
2016-5-19
在线时间
392 小时
最后登录
2019-4-23
楼主 2018-11-5 19:42:50 显示全部楼层
随幻Kaller 发表于 2018-11-5 16:19
如果单纯的只是为了防止被删除影响数目 何不这样
int len = plateList.Count;
for (int i = 0; i < len ; i ...

正是因为数目是 删之前的, 所有导致遍历时候 删除,导致越界的
回复

使用道具 举报

6蛮牛粉丝
1330/1500
排名
3221
昨日变化

48

主题

426

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
149133
好友
20
蛮牛币
1101
威望
0
注册时间
2016-5-19
在线时间
392 小时
最后登录
2019-4-23
楼主 2018-11-5 19:43:52 显示全部楼层
秋秋秋秋秋水 发表于 2018-11-5 15:55
遍历数组前,拿一个新列表用来遍历,遍历后更新这个新列表。保证此次遍历时列表长度不会有变化。或者写一个 ...

链表中的数组是根据时间自动删除的。 也就是链表中每个物体计时器到时间,自己删除,这个怎么控制
回复

使用道具 举报

6蛮牛粉丝
1330/1500
排名
3221
昨日变化

48

主题

426

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
149133
好友
20
蛮牛币
1101
威望
0
注册时间
2016-5-19
在线时间
392 小时
最后登录
2019-4-23
楼主 2018-11-5 19:45:07 显示全部楼层
MaxSong 发表于 2018-11-5 16:51
方法一:利用Unity脚本的生病周期进行List的增删遍历
方法二:遍历的时候判断一下当前i是否大于等于List的c ...

你的第一种方法再详细解释下。 没明白
回复

使用道具 举报

6蛮牛粉丝
1330/1500
排名
3221
昨日变化

48

主题

426

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
149133
好友
20
蛮牛币
1101
威望
0
注册时间
2016-5-19
在线时间
392 小时
最后登录
2019-4-23
楼主 2018-11-5 19:46:40 显示全部楼层
随幻Kaller 发表于 2018-11-5 16:19
如果单纯的只是为了防止被删除影响数目 何不这样
int len = plateList.Count;
for (int i = 0; i < len ; i ...

记录数量这个不行的。 因为我是在遍历过程中删除的数据,导致链表变化了。所以才越界的
回复

使用道具 举报

6蛮牛粉丝
1330/1500
排名
3221
昨日变化

48

主题

426

帖子

1330

积分

Rank: 6Rank: 6Rank: 6

UID
149133
好友
20
蛮牛币
1101
威望
0
注册时间
2016-5-19
在线时间
392 小时
最后登录
2019-4-23
楼主 2018-11-5 19:48:40 显示全部楼层
MaxSong 发表于 2018-11-5 16:51
方法一:利用Unity脚本的生病周期进行List的增删遍历
方法二:遍历的时候判断一下当前i是否大于等于List的c ...

for (int j = 0; j < LastIdDic.Length; j++)
                    {
                          if(i>=LastIdDic.Count)
                              return;
                        if (LastIdDic[j]!=null)
                        {
                            if (LastIdDic[j].obj == plateObj)
                            {
                                LastIdDic[j] = null;
                            }
                        }                        
                    }

第二种方法是这样吗??
回复

使用道具 举报

7日久生情
2062/5000
排名
1627
昨日变化

19

主题

470

帖子

2062

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
218268
好友
5
蛮牛币
2394
威望
0
注册时间
2017-4-18
在线时间
763 小时
最后登录
2019-4-18

活力之星

2018-11-6 08:43:58 显示全部楼层
你可以试试while循环,做一个index时刻与count对比,超过了就跳出。不知道可以解决不
回复

使用道具 举报

6蛮牛粉丝
1333/1500
排名
3110
昨日变化

5

主题

361

帖子

1333

积分

Rank: 6Rank: 6Rank: 6

UID
234410
好友
2
蛮牛币
1507
威望
0
注册时间
2017-7-26
在线时间
477 小时
最后登录
2019-4-24
2018-11-6 09:24:42 显示全部楼层
刘彦磊 发表于 2018-11-5 19:46
记录数量这个不行的。 因为我是在遍历过程中删除的数据,导致链表变化了。所以才越界的 ...

这个不是链表 是列表
你可以将要删除的索引存起来 然后循环之后 统一从后往前删除
还有 在循环中删除本体本来就是不必要的 所以设计上也可以适当修改
回复

使用道具 举报

5熟悉之中
721/1000
排名
4111
昨日变化

0

主题

37

帖子

721

积分

Rank: 5Rank: 5

UID
252114
好友
0
蛮牛币
569
威望
0
注册时间
2017-11-2
在线时间
314 小时
最后登录
2019-4-11
2018-11-6 09:28:48 显示全部楼层
我觉得每个物体计时器到时间,自己删除,然后同时还要一直遍历有点困难啊,可以统一写个每隔一段时间后先遍历,然后是增加删除的方法,就是每个物体自己的计时,如果到时间了,删掉然后更新等隔一段时间再从新遍历
回复

使用道具 举报

7日久生情
3145/5000
排名
458
昨日变化

2

主题

140

帖子

3145

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
121784
好友
0
蛮牛币
10313
威望
0
注册时间
2015-9-9
在线时间
1381 小时
最后登录
2019-4-23
2018-11-6 09:35:52 显示全部楼层
请使用ToArray将List转为数组(本质是复制操作),然后遍历这个数组
回复

使用道具 举报

6蛮牛粉丝
1069/1500
排名
13983
昨日变化

5

主题

196

帖子

1069

积分

Rank: 6Rank: 6Rank: 6

UID
26011
好友
0
蛮牛币
1463
威望
0
注册时间
2014-5-21
在线时间
804 小时
最后登录
2019-4-24
2018-11-6 11:31:43 显示全部楼层
多线程。lock锁。一个线程删,一个线程增。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则