[Error] Unity - "OnDestroy" does not always execute

qweasfjbv·2025년 1월 30일

Error

목록 보기
6/7

개요

		private void Awake() 
        {
			Managers.[ActionName] -= OnTypeChanged;
			Managers.[ActionName] += OnTypeChanged;
        }

		private void OnDestroy()
		{
			Managers.[ActionName] -= OnTypeChanged;
		}

Unity를 사용하다 보면 위와 같이 Action (혹은 Func) 와 같이 대리자를 사용하여 Manager에서 호출 시점을 정하고 싶을 때가 있습니다.

이 때, Destroy가 되는 오브젝트라면 OnDestroy 콜백 함수에서 Action에 넣어뒀던 함수들을 빼주어야 합니다.

하지만 OnDestroy는 항상 호출되지는 않습니다. 즉, 아래와 같은 오류가 발생할 수 있습니다.

이미 Destroy 되었음에도 Action에 의해 함수가 호출되기 때문입니다.

해결

해당 Unity Document 를 보시면 원인을 알 수 있습니다.

Note: OnDestroy will only be called on game objects that have previously been active.

한 번도 Active 되지 않은 오브젝트의 경우에는 OnDestroy 가 호출되지 않는다고 나와있습니다.
저는 Prefab은 Active 상태였지만, Active되지 않는 부모의 자식으로 Instantiate 를 해주었기 때문에 이러한 문제가 발생하였습니다.


해결방법 1

근본적인 해결 방법은 아니지만, 에러가 나는 함수에서 아래와 같은 코드를 호출하면 에러가 발생하지 않습니다.

		public void Func1() {
        
            if (this == null) return;

하지만 Action에 파괴된 오브젝트의 함수가 메모리를 차지하고 있는게 마음에 걸리긴 합니다.

해결 방법 2

		private void OnDestroy()
        {
            Clear();
		}

        public void Clear()
		{
			Managers.Input.OnBuildingTypeChanged -= OnTypeChanged;
		}

저는 위와 같이 Clear() 함수를 따로 만들고, 이를 Destroy 함수를 호출하는 부분에서 Clear 함수를 따로 호출하는 방식으로 수정하였습니다.

참고자료


https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.OnDestroy.html

0개의 댓글