[Unity] Unity Monobehaviour 생성자 종료자 호출 순서
카테고리: Unity
생성자와 종료자에 관한 수업자료 준비를 하기 위해 유니티에서 생성자와 소멸자를 만들어 간단히 로그를 찍어 보았습니다.
생성자와 종료자
생성자는 객체가 생성할 때 호출되고, 종료자는 객체의 참조가 null이 되거나, 가비지컬렉터가 메모리에서 Dispose() 해줄 때 호출됩니다.
사용법은 다음과 같습니다.
using UnityEngine;
public class SomeClass
{
//생성자
public SomeClass()
{
Debug.Log("생성자 입니다.");
}
//소멸자
~SomeClass()
{
Debug.Log("소멸자 입니다.");
}
}
Unity 에서 생성자 종료자 여러번 호출되는 현상
그래서 이것들을 테스트 하기 위해 호출하는 클래스를 하나 만들었습니다.
public class ConstructorTest
{
public void Awake()
{
SomeClass someClass = new SomeClass();
someClass = null;
}
}
이렇게 만들어 주고 로그를 찍어보니 제가 예상한대로 생성자 한번 소멸자 한번이 출력 되었습니다.
그리고 전역변수로도 만들어서 테스트 해봐야지 하고 다음과 같이 스크립트를 짰습니다.
public class ConstructorTest
{
private SomeClass someClass = new SomeClass();
private void Awake()
{
someClass = null;
}
}
이렇게 하고 짰는데, 예상했던 결과랑 많이 달랐습니다.
생성자와 소멸자가 여러번 호출되는 것이었습니다.
이 문제는 유니티의 코어 엔진이 C++ 이라서 생기는 문제였습니다.
C++ 에는 멤버 이니셜라이저 (멤버변수에서 바로 new 키워드로 생성하는 것)이 없기 때문에, 별도로 생성자를 억지로 만들어서 넣는 과정 때문에 이러한 문제가 생긴다고 합니다.(물론 지금 C++ 버전은 Member Initializer 가 있습니다.)
그리고 소멸자는 유니티의 가비지 컬렉터가 엉망이라서 그렇다고 합니다.
결론
생성자와 소멸자가 여러번 호출되는 현상은, 유니티 때문입니다. ㅋㅋㅋㅋㅋㅋ 그래서 변수를 초기화 하고 등록하는 것은 무조건 생성자에서 해주는 것이 가장 깔끔합니다. 또한, 유니티의 MonoBehaviour를 상속받은 녀석들은 UnityEvent에서 초기화를 해주는 것이 좋습니다. 하지만, Unity의 MonoBehaviour도 초기화 순서를 완전히 보장하지 못하기 때문에 LazyInit 기법을 사용하여 초기화 하는 것이 좋습니다.
결국 객체를 생성해주는 정확한 타이밍이 보장되는 곳에서 생성을 해주는게 좋습니다.
댓글 남기기