翻車了!!!一個小例子帶你了解閉包。
事故現場:
場景:6個button,上方1個text。點選button,text會顯示button上的數字。
代碼如下:
//在unity裡面指派
public List buttons = new List
事故原因:
閉包。标題那麼長跟閉包有什麼關系?因為上述問題會引起閉包。為什麼标題中不直接寫出關鍵字閉包?因為叫的出閉包的人基本上都會避免這個問題,這篇文章主要針對新人,那些沒聽過閉包的人。
事故分析:
1、什麼是閉包?我也不知道哈,非科班,定義百度一下吧。
2、怎麼會産生閉包?内部函數使用了外部函數的局部變量。内部函數:是我對匿名函數,lambda表達式等函數嵌套情況的稱呼。如上述例子:外部函數Addfun,内部函數是lambda表達式,i是外部函數for循環中的局部變量,内部函數lambda表達式使用了i這個局部變量。
3、閉包會導緻什麼的結果?閉包會延長所用外部函數局部變量的生命周期,或者說是局部變量變成了全局變量。
記憶體分析:
通俗的講就是局部變量i從沒被釋放,一直存在記憶體中,随着i++,值增到了6,所有button的點選函數都是傳進的i+1,也就是7,為實參,是以fun函數列印的數字為7
處理辦法:
重新申請記憶體。代碼如下:
void AddFun()
{
for (int i = 0; i < buttons.Count; i++)
//重新申請的記憶體
int index = i;
buttons[i].onClick.AddListener(() => Fun(index + 1));
}
void Fun(int i)
text.text = i.ToString();
print(i);
通過初始化重新申請了6塊記憶體,内塊記憶體儲存了不同的index值(index值是由i指派而來)。雖然index變量的生命周期也被延長,但是不同的button的點選函數通路的傳進參數的記憶體不同,是以fun函數列印的數字也就不同。
事件解決:
拓展:
其實閉包在腳本語言中非常常見,也非常有用。以lua為例,代碼如下:
function OutSideFun()
local i=0
local function InsideFun()
i=i+1
print(i)
end
return InsideFun
local fun=OutSideFun()
fun()
那麼自己可以試試輸出值是多少,分析一下為什麼是這樣。
更多unity2018課程請直接到paws3d上查找。