天天看點

Unity_新手必懂知識點

翻車了!!!一個小例子帶你了解閉包。

事故現場:

場景: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上查找。

繼續閱讀