/**
*Copyright(C) 2019 by #COMPANY#
*All rights reserved.
*FileName: #SCRIPTFULLNAME#
*Author: #AUTHOR#
*Version: #VERSION#
*UnityVersion:#UNITYVERSION#
*Date: #DATE#
*Description:
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Text1 : MonoBehaviour
{
public Transform btn;
List<int> list = new List<int> {
1,2,3,4,5
};
// Use this for initialization
void Start()
{
for (int i = 0; i < list.Count; i++)
{
Transform go = Instantiate(btn);
go.transform.position = btn.transform.position + Vector3.down * i*30;
go.gameObject.SetActive(true);
go.GetComponent<Button>().onClick.AddListener(() => {
go.Find("Text").GetComponent<Text>().text = i.ToString();
});
go.SetParent(transform);
}
}
}
這個腳本掛在畫布上 創(chuàng)建一個Btn拖到屏幕上方的位置失活

image.png
然后我們點擊會把I傳遞給Text
點一輪都是5

image.png
因為他一開始幫你注冊了事件 但是Btn里面點擊激活并沒有,在你點的時候循環(huán)已經(jīng)完畢,一直是最大值,在點擊的時候就所有Btn只會被傳遞最大值的i,但是不是從0開始最后不應(yīng)該是4停止嗎,因為for循環(huán)底層是
public void For(ref int i,int maxCount,Action func)
{
while (i<maxCount)
{
func();
i++;
}
}
int j = 0;
For(ref j, 4, () => { Debug.Log(j); });

image.png
他的i++是最后執(zhí)行的也就是說最后i++還是執(zhí)行了。
至于i++和++i for循環(huán)結(jié)果是沒區(qū)別的 詳細的可以看
https://blog.csdn.net/tsvico/article/details/74943281
/**
*Copyright(C) 2019 by #COMPANY#
*All rights reserved.
*FileName: #SCRIPTFULLNAME#
*Author: #AUTHOR#
*Version: #VERSION#
*UnityVersion:#UNITYVERSION#
*Date: #DATE#
*Description:
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Text1 : MonoBehaviour
{
public Transform btn;
List<int> list = new List<int> {
1,2,3,4,5
};
// Use this for initialization
void Start()
{
for (int i = 0; i < list.Count; i++)
{
Transform go = Instantiate(btn);
go.transform.position = btn.transform.position + Vector3.down * i*30;
go.gameObject.SetActive(true);
var iCache = i;
go.GetComponent<Button>().onClick.AddListener(() => {
go.Find("Text").GetComponent<Text>().text = iCache.ToString();
});
go.SetParent(transform);
}
}
}
然后如果用臨時變量在注冊Btn之前存一下呢

image.png
正常了,原因可能是每次循環(huán)都會New出一個新的iCache,而注冊Btn里面的iCache是指向外面每次for循環(huán)產(chǎn)生的與他們同一次循環(huán)產(chǎn)生的iCache

image.png
/**
*Copyright(C) 2019 by #COMPANY#
*All rights reserved.
*FileName: #SCRIPTFULLNAME#
*Author: #AUTHOR#
*Version: #VERSION#
*UnityVersion:#UNITYVERSION#
*Date: #DATE#
*Description:
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Text1 : MonoBehaviour
{
public Transform btn;
List<int> list = new List<int> {
1,2,3,4,5
};
// Use this for initialization
void Start()
{
int iCache;
for (int i = 0; i < list.Count; i++)
{
Transform go = Instantiate(btn);
go.transform.position = btn.transform.position + Vector3.down * i*30;
go.gameObject.SetActive(true);
iCache = i;
go.GetComponent<Button>().onClick.AddListener(() => {
go.Find("Text").GetComponent<Text>().text = iCache.ToString();
});
go.SetParent(transform);
}
}
}
然后把iCache提取到外部一直覆蓋為什么現(xiàn)在都成四了,因為結(jié)束時i++執(zhí)行后就沒有再進入循環(huán)所以iCache是不會多增加一次
然后用類傳入i呢,結(jié)果正常應(yīng)該是傳入的時候自動幫你新建了一個臨時變量儲存起來,類似于之前的 var iCache=i;的操作
using System;
/**
*Copyright(C) 2019 by #COMPANY#
*All rights reserved.
*FileName: #SCRIPTFULLNAME#
*Author: #AUTHOR#
*Version: #VERSION#
*UnityVersion:#UNITYVERSION#
*Date: #DATE#
*Description:
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Text1 : MonoBehaviour
{
public Transform btn;
List<int> list = new List<int> {
1,2,3,4,5
};
// Use this for initialization
void Start()
{
for (int i = 0; i < list.Count; i++)
{
CreatBtn(i);
}
//for (int k = 0; k < 4; ++k)
//{
// Debug.Log(k);
//}
//int j = 0;
//For(ref j, 4, () => { Debug.Log(j); });
}
public void CreatBtn(int i)
{
Transform go = Instantiate(btn);
go.transform.position = btn.transform.position + Vector3.down * i * 30;
go.gameObject.SetActive(true);
go.GetComponent<Button>().onClick.AddListener(() =>
{
go.Find("Text").GetComponent<Text>().text = i.ToString();
});
go.SetParent(transform);
}
public void For(ref int i, int maxCount, Action func)
{
while (i < maxCount)
{
func();
i++;
}
}
}

image.png
因為這個坑讓我很多靠順序生成讀表的東西都迷之錯誤,然后在這里探究下以防以后出現(xiàn)再傻掉了
之后無意間看到其實這個叫閉包陷阱
這個是概念
內(nèi)層的函數(shù)可以引用包含在它外層的函數(shù)的變量,即使外層函數(shù)的執(zhí)行已經(jīng)終止。但該變量提供的值并非變量創(chuàng)建時的值,而是在父函數(shù)范圍內(nèi)的最終值。
用臨時變量接收相當于每次new出來這個對象
詳細的
https://www.cnblogs.com/jiejie_peng/p/3701070.html