예전 Coroutine 에 대해 자세히 알아본 내용을 정리한다.
Coroutine은 IEnumerator 의 반환 타입을 가지고, 함수 Body 에 yield return 문을 포함한 함수이다.
그냥 일반 함수처럼 (반환 형태 void 인 애들처럼) 호출하는 것 또한 가능하다!
그럼, Coroutine을 IEnumerator 와 yield return 이 기능함으로써 만들어진다는 것인데, 이것이 무엇일까?
Class 내부의 Collection을 반복할 수 있도록 지원한다.
Collection : object (객체)를 group으로 관리하는 방법. Array, Collection 두 가지가 존재한다.
위의 설명으로는 부족한 점이 있을 것 같아 추가 서술 :
IEnumerator interface 를 구현한 Class의 경우, 그 내부 구성요소는
public interface IEnumerator {
object Current {get;} // 현재 위치 데이터 (현재 위치의 Collection 요소를 return 한다.)
bool MoveNext(); // 다음 위치로 이동한다. 데이터가 있으면 true, 없으면 false 를 반환한다.
void Reset(); // index를 초기 위치로 설정한다.
}
Class 내부 Collection 을 반복할 수 있도록 지원하는 IEnumerator를 노출시킨다.
public interface IEnumerable {
IEnumrator GerEnumerator(); // 말 그대로, IEnumerator를 노출한다. 반환하여, 해당 interface의 정보가 드러나도록 만들어주는 함수를, 해당 class 내에 구현하도록 한다.
}
즉, IEnumerator로 구현된 Class 가 해당 Class 내부에 들어있는 Collection의 직접적인 순회를 책임지며.
IEnumerable 의 경우, IEnumerator 에 관한 정보를 가지고 있다.
예를 들어 설명해본다.
A Class 가 있다고 하자.
List <'A'> 를 Field 로서 가지며, IEnumerator 로 구현된, AEnum Class 가 있다 하자.
AEnum Class는 Field 를 반복하거나 탐색할 수 있다.
이 AEnum 을 Field 로서 가지고 있는, IEnumerable 로 구현된, AEnumerable Class가 있다 하자. 해당 Class 는 GetEnumerator() 가 구현되어 있을 것이고, 해당 GetEnumerator() 는 AEnum을 반환할 것이다.
대강 이렇게 구성되는 것.
IEnumerable 로 구현된, Class 내부에 직접적으로 Collection이 존재하며, GetEnumerator 에서 반환해 줄 때, IEnumerator 를 구현한 Type 을 바로 new 로 생성하여 반환하는 것도 가능하다.
링크의 Person, PeopleEnum, People Class 예시 참고
또한 IEnumerable 이 여러 IEnumerator를 가지고 있을 수도 있다.
Foreach 의 실체 : GetEnumerator() 함수를 통해 열거자 IEnumerator 객체를 리턴 받고 이를 통해 데이터를 순회한다.
즉, 위의 정리에서의 예시를 바탕으로 생각해보면, foreach(A "변수이름" in "AEnumerable type 에 해당하는 변수이름") 이어야 한다는 것이다.
(위의 A Class, AEnum Class, AEnumerable Class 로서 서술한 예시 참고.)
더 간략하게 정리해보면, 아래 코드와 foreach 가 동일하다고 보면 된다.
IEnumerator e = AEnumerable변수이름.GetEnumerator();
while(e.MoveNext()) {
// Body for foreach : foreach 안에 들어갈 내용과 동일.
}
Microsoft 에서는 yield keyword 를 실행문에서 사용한다는 것은, yield 가 사용된 그 해당 method, operator, get Accessor 등이 '반복자(Iterator)' 임을 의미한다.
해당 keyword 를 method 에서 사용한 경우를 생각해보자.
즉, yield return 을 사용한 method 는, 위에 따라 반복자가 된다.
IEnumerator 와 yield 를 이용하여, 일반적인 상황에서 함수의 실행이 직렬적으로 처리되던 것을 별도의 Thread 처럼 실행시킬 수 있도록 만든 것.
아래 내용은 알고 있는 내용이라 별도 정리 필요성을 못 느껴 수기만 옮긴다.
Coroutine 으로서 IEnumerator 의 반환형태를 가진 method 를 실행한다.
이는 즉, Coroutine 을 통해 IEnumerator method 가 실행된 경우, foreach 의 형태처럼 해당 함수의 부분들이 실행되나, 반환 받는 것에 따라 Unity 내부적, 혹은 C# 내부적으로 마련되어져 있는 특별한 기능들이 동작한다는 것을 의미한다.
ex - yield return new WaitForSecond(?f);
등.
좋은 공부가 되었습니다. 감사합니다!