Version: 2019.3
언어: 한국어
UnityEvent
중요 클래스

Null 레퍼런스 제외란 무엇입니까?

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이 발생합니다.

Null 체크

이 경우 실망스러울 수 있지만, 스크립트를 더 신중하게 작성하면 됩니다. 간단한 예제에서는 코드를 다음과 같이 변경하여 문제를 해결할 수 있습니다.

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을 방지할 수 있습니다.
UnityEvent
중요 클래스