NullReferenceException
은 오브젝트를 레퍼런스하지 않는 레퍼런스 변수에 액세스하려고 하면 발생합니다. 레퍼런스 변수가 오브젝트를 참조하지 않는 경우 null
로 처리됩니다. 런타임은 변수가 null
일 때 NullReferenceException
을 표시하여 오브젝트에 액세스하려고 함을 알립니다.
C# 및 JavaScript의 레퍼런스 변수는 C와 C++의 포인터와 개념적으로 비슷합니다. 디폴트 레퍼런스 타입은 null
로, 오브젝트를 레퍼런스하지 않음을 나타냅니다. 따라서 레퍼런스되고 있는 오브젝트에 액세스하려고 하는 경우 이런 오브젝트가 없으면 NullReferenceException
가 발생합니다.
코드에서 NullReferenceException
이 발생하면 사용 전에 변수를 설정하지 않았음을 의미입니다. 다음과 같은 오류 메시지가 나타납니다.
NullReferenceException: Object reference not set to an instance of an object
at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10
오류 메시지를 통해 스크립트 파일 Example.cs
의 10번째 줄에서 NullReferenceException
이 발생했음을 알 수 있습니다. Start ()
함수 내부에서 예외가 발생했다는 사실도 알 수 있습니다. 따라서 Null 레퍼런스 제외를 쉽게 찾고 해결할 수 있습니다. 예제에서 코드는 다음과 같습니다.
//c# example
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
// Use this for initialization
void Start () {
GameObject go = GameObject.Find("wibble");
Debug.Log(go.name);
}
}
코드에서는 단순히 “wibble”이라는 게임 오브젝트를 찾아봅니다. 예제에는 이름이 “wibble”인 게임 오브젝트가 없으므로 Find()
함수에서 null
이 반환됩니다. 다음 줄(9번째 줄)에서는 go
변수를 사용해 레퍼런스된 게임 오브젝트의 이름을 출력하려고 합니다. 존재하지 않는 게임 오브젝트에 액세스하려고 하기 때문에 런타임에 NullReferenceException
이 발생합니다.
이 경우 실망스러울 수 있지만, 스크립트를 더 신중하게 작성하면 됩니다. 간단한 예제에서는 코드를 다음과 같이 변경하여 문제를 해결할 수 있습니다.
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
void Start () {
GameObject go = GameObject.Find("wibble");
if (go) {
Debug.Log(go.name);
} else {
Debug.Log("No game object called wibble found");
}
}
}
이제 go
변수를 사용하여 작업하려고 하기 전에 변수가 null
이 아닌지 확인합니다. null
이면 메시지를 표시합니다.
인스펙터에서 초기화해야 하는 변수를 사용해도 NullReferenceException
이 발생할 수 있습니다. 초기화하는 것을 잊어버리면 변수가 null
이 됩니다. 트라이/캐치 블록(try/catch block)을 사용하는 방법으로 NullReferenceException
를 처리할 수도 있습니다. 코드 예제:
using UnityEngine;
using System;
using System.Collections;
public class Example2 : MonoBehaviour {
public Light myLight; // set in the inspector
void Start () {
try {
myLight.color = Color.yellow;
}
catch (NullReferenceException ex) {
Debug.Log("myLight was not set in the inspector");
}
}
}
코드 예제에서 myLight
라는 변수는 인스펙터 창에서 설정해야 하는Light
입니다. 변수를 설정하지 않으면 디폴트인 null
로 설정됩니다. try
블록에서 광원 컬러를 변경하려고 하면 NullReferenceException
이 발생하고, catch
블록에서 픽업합니다. catch
블록은 아티스트와 게임 디자이너에게 더 유용할 수 있는 메시지를 표시하고, 인스펙터에서 광원을 설정해야 한다고 다시 알립니다.
NullReferenceException
은 스크립트 코드에서 설정되지(레퍼런스하지) 않은 변수와 오브젝트를 사용하려고 할 때 발생합니다.null
을 체크하거나 트라이/캐치 블록을 사용하는 코드를 작성하여 NullReferenceException
을 방지할 수 있습니다.