StartCoroutine的使用:
IEnumerator Wait(float waitTimeValue){
//things before wait
yield return new WaitForSeconds(waitTimeValue);
//thigs after wait;
}
SatrtCoroutine(Wait(5.0f));
刚接触StartCoroutine时,只知道可以通过这种方式进行延时操作,至于IEnumerator类型,yield return这种奇怪的语句以及
调用的时候要在StartCoroutine()里进行这几个问题,一直是一脸蒙蔽,什么鬼嘛这是,
在慢慢看了一些博主的文章后,对这几个问题有了初步的认识,就在这里记录下来:
1.IEnumerator
IEnumerator和yield return会构造出一个迭代器,迭代器几乎经常在用,例如:
int[] array=new int[]{1,2,3};
foreach(int i in array){
print(i);
}
数组的遍历过程实际上就是一个迭代器应用过程,只不过这个迭代器是由编译器帮我们实现,在编译器的内部,上面的代码类似这个样子(真正的比下面的要复杂):
int[] array=new int[]{1,2,3};
IEnumerator e=array.GetEnumerator();
while(e.MoveNext()){
print(Current);
}
至于迭代器内的方法MoveNext()和属性Current是IEnumerator这个接口定义的,这里是IEnumerator的完整声明:
public interface IEnumerator
{
//
// 摘要:
// 获取集合中的当前元素。
//
// 返回结果:
// 集合中的当前元素。
//
// 异常:
// T:System.InvalidOperationException:
// 枚举数定位在该集合的第一个元素之前或最后一个元素之后。
object Current { get; }
//
// 摘要:
// 将枚举数推进到集合的下一个元素。
//
// 返回结果:
// 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
//
// 异常:
// T:System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
bool MoveNext();
//
// 摘要:
// 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
//
// 异常:
// T:System.InvalidOperationException:
// 在创建了枚举数后集合被修改了。
void Reset();
}
2.yield return是干什么的
yield return 是C#2.0以后引入的现实迭代器的一种简便语法,在之前如果要实现一个完整的迭代器
需要实现IEnumerable和IEnumerator这两个接口,而使用yield retrun可以省略这两个步骤:
例如:
IEnumerator Test(){
yield return 1;
yield retutn 2;
yield retrun 3;
}
编译器会生成类似代码:
public class InnerEnumerable:IEnumerable{
public class InnerEnumerator:IEnumerator{
int[] array=new int[]{1,2,3};
int currentIndex=-1
public bool MoveNext(){
++currentIndex;
return current
public Object Current{
get{return array[currentIndex];}
}
public void Reset(){
throw new Exception("error");
}
}
public IEnumerator GetEnumerator(){
return new InnerEnumerator();
}
}
IEnumerator Test(){
InnerEnumerable e= new InnerEnumerable();
return e.GetEnumerator();
这里可以将IEnumerable看成是IEnumerator的工厂模式,通过yield return让编译器实现IEnumerable和IEnumerator这两个接口
3.为什么调用的时候要被StartCoroutine()调用
这里就和实现延时过程有关系了,WaitForSeconds,WaitForEndFrame等类中并没有进行延时的处理,而他们的父类,yieldInstruction中
也并没有进行延时的处理,因为真正的延时处理是在StartCoroutine中进行的,StartCoroutine()传入的参数是IEnumerator,
StartCoroutine会对IEnumerator的MoveNext()进行调用,但是,如果这个IEnumerator是WaitForSeconds,WaitFaorEndFrame等类型
StartCoroutine就会特殊对待,执行完延时等待后,再调用MoveNext();
http://blog.csdn.net/tkokof1/article/details/11842673 这篇博主实现了自己的WaitForSeconds的功能,写的非常详细,以上内容也是基于此文进行的整理
4.StartCoroutine的嵌套执行顺序
void Start () { Debug.Log("start1"); StartCoroutine(Test()); Debug.Log("start2"); } IEnumerator Test() { Debug.Log("test1"); yield return StartCoroutine(DoSomething()); Debug.Log("test2"); } IEnumerator DoSomething() { Debug.Log("do something 1"); yield return null; Debug.Log("do something 2"); }输出结果:
start1
test1
do something 1
start2
do something 2
test2
StartCoroutine中嵌套一个yield return StartCoroutine,第一个StartCoroutine会等到第二个StartCoroutine中所有代码结束后再继续执行,而第二个StartCoroutine中的yield语句会先返回第一个,然后立即返回他的调用处,也就是调用处会继续执行,而第一个StartCoroutine会等待第二个执行完再继续执行。