今天咱就說說協(xié)同程序coroutine酱畅。
什么是協(xié)同程序
先說說啥是協(xié)程:它的表現(xiàn)形式非常像線程留储,對(duì)線程有過接觸的朋友可能更理解我這句話的意思炼鞠,你沒接觸過線程,那么理解它會(huì)有一些難度眶明。但是它不存在線程安全問題,可以放心使用筐高。
是這樣的:在操作系統(tǒng)層面搜囱,也就是更古老的大神們,覺得“并發(fā)”是一個(gè)很時(shí)髦的東西柑土,很好使蜀肘,于是他們?cè)试S操作系統(tǒng)中開啟進(jìn)程。后來稽屏,他們覺得一個(gè)進(jìn)程中扮宠,如果也能并發(fā)該多好,那么線程應(yīng)運(yùn)而生(這些都是身為碼農(nóng)應(yīng)該知道的一些常識(shí):一個(gè)系統(tǒng)上可以運(yùn)行多個(gè)進(jìn)程狐榔,一個(gè)進(jìn)程可以并發(fā)多個(gè)線程)坛增。
但是由于我們的unity是單線程的,那么還有一句不這么耳熟能詳?shù)脑挘阂粋€(gè)線程可以多協(xié)程薄腻。于此看來收捣,coroutine可以說是在unity主線程中“并發(fā)”的很多協(xié)程。這個(gè)“并發(fā)”為什么加引號(hào)庵楷,這將是我們研究的重要內(nèi)容罢艾。介紹了協(xié)同的定義,那么可以研究一下它在項(xiàng)目中究竟會(huì)怎么用尽纽。下面就是面試考題中可能遇到的幾種協(xié)同程序的用法:
1.不使用協(xié)同啟動(dòng)一個(gè)返回迭代器的函數(shù)咐蚯。
void 家里來客人()
{
沏茶();
與客人聊天()蜓斧;
}
IEnumerator 沏茶()仓蛆;
2.在迭代器函數(shù)中,yield return 一個(gè)協(xié)同啟動(dòng)挎春。 如
void 家里來客人()
{
StartCoroutine(沏茶())看疙;
與客人聊天()豆拨;
}
IEnumerator 沏茶()
{
yield return StartCoroutine(做水());
找茶葉罐()能庆;
}
IEnumerator 做水()施禾;
void 找茶葉罐();
3.在迭代器函數(shù)中搁胆,直接啟動(dòng)一個(gè)協(xié)同弥搞。如
void 家里來客人()
{
StartCoroutine(沏茶());
與客人聊天()渠旁;
}
IEnumerator 沏茶()
{
StartCoroutine(做水())攀例;
找茶葉罐();
}
IEnumerator 做水()顾腊;
void 找茶葉罐()粤铭;
下面逐條分析一下把。
- 對(duì)于第一條:這種用法杂靶,迭代器“沏茶”梆惯,根本不會(huì)被并發(fā),比如在這種情況下吗垮,雖然沏茶是一個(gè)迭代器函數(shù)垛吗,但是你如果這么執(zhí)行,也會(huì)是沏完了茶(徹底沏完了茶)再跟客人聊天烁登。如果沏茶很費(fèi)時(shí)間怯屉,那么不好意思,你在這段時(shí)間內(nèi)防泵,都不會(huì)跟客人聊天蚀之。這里迭代器等于白費(fèi)。相當(dāng)于普通函數(shù)捷泞。
- 對(duì)于第二條:你在startcoroutine之后足删,立即開始并發(fā),也就是你一邊執(zhí)行沏茶锁右,一邊開始跟客人聊天了∈埽現(xiàn)在進(jìn)來看看你沏茶的時(shí)候。在沏茶的協(xié)同中咏瑟,你先yield return 做水拂到。這句話的意思就是,“等待做完水了”码泞,再開始找茶葉罐兄旬。值得注意的是,你在做水,找茶葉罐的時(shí)候领铐,已經(jīng)開始跟客人聊天了悯森。
- 對(duì)于第三條:你一遍執(zhí)行沏茶,一遍與客人聊天绪撵。在你沏茶的時(shí)候瓢姻,你是一邊做水,一邊找茶葉罐的音诈。
對(duì)于這個(gè)例子來看呢幻碱。有這么幾條收獲:
- yield return 跟return 沒有任何關(guān)系,yield return xxx 翻譯成人話就是“等待xxx返回之后”细溅,是一個(gè)阻塞協(xié)同程序的操作褥傍。
- 開啟協(xié)同程序,實(shí)現(xiàn)了偽并發(fā)喇聊,雖說看起來像并發(fā)摔桦,但是還是有先后執(zhí)行次序,所以跟線程有本質(zhì)的不同——線程理論上來說承疲,先后次序是不可預(yù)知的——除非你用信號(hào)量等等進(jìn)行人為控制哈。
- 開啟協(xié)同程序鸥咖,必須得是一個(gè)返回迭代的函數(shù)燕鸽。否則編譯不過。但是返回迭代的函數(shù)可以不在協(xié)同中調(diào)用啼辣,這樣編譯是通過的啊研,但是基本不會(huì)這么寫,代碼不干凈鸥拧。
主要的骨頭已經(jīng)啃了党远,剩下一個(gè)就是協(xié)同程序什么時(shí)候才算完結(jié)?
- 碰見yield break——直接跳出攜程富弦,對(duì)某些判定失敗必須跳出的時(shí)候沟娱,比如加載AssetBundle的時(shí)候,WWW都失敗了腕柜,后邊加載bundle沒有必要了济似,這時(shí)候可以yield break。這個(gè)語句非常有用盏缤。
- 執(zhí)行到最后一行——最后一行不一定非得是 yield return xxx砰蠢;我經(jīng)常最后一句是一個(gè) excute delegate什么的。
- 補(bǔ)充:yield return null唉铜;yield return 0台舱; 均不算完結(jié)協(xié)同程序!L读鳌>和铩柜去!
弄懂了這些,自己去揣摩揣摩碰声,就能搞定協(xié)同啦诡蜓。難點(diǎn)就是這些。它雖然惡心胰挑,但是并不難蔓罚,希望對(duì)大家有幫助!