• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

NullReferenceException을 기대했는데....

21.05.04 04:40 작성 조회수 188

0

쓰신 코드 보니까 Destroy 관련해서 NullReferenceException을 유도해낼 수 있을거라 생각을 했는데 그렇지가 않아서 질문을 드립니다

    public List<GameObject> objs;

    void Start()

    {

        objs = new List<GameObject>();

        GameObject go1 = new GameObject();

        GameObject go2 = new GameObject();

        objs.Add(go1);

        //objs.Add(go2);

        //Destroy(objs[0]);

        Destroy(go1);

        //objs.RemoveAt(0);

        print(go1.name);

    }

이게 제가 테스트 해본 내용입니다

제 생각에는 objs에 go1을 추가하고, 

 Destroy(go1); 실제 go1을 없애고

objs.RemoveAt(0)을 하지 않았기에 해당 리스트의 참조변수는 남아있으나 참조 대상이 없어져버려서(go1) nullReferenceException이 일어날거라고 생각을 했습니다

결과는 일어나지 않았고 그래서 그 앞에 Destroy(objs[0]);을 추가 해봤지만 print(go1.name);는 앞선 경우와 마찬가지로 작동을 하더군요

제 생각에 이러는 이유는 계층뷰에서 해당 게임 오브젝트가 존재해서 같은데 이유가 뭔가요?

답변 1

답변을 작성해보세요.

1

안녕하세요. 요즘 바빠서 답변이 늦었습니다. 죄송합니다. 

Destroy 가 되었어도 현재 Start 에서 Destroy 를 실행했기에 현재 프레임이 끝나고 나서 다음 프레임에서 print(go1.name); 을 실행해야 오류가 발생합니다. 

업데이트에서 실행해보면 오류를 발생시킬수 있는데 이 경우 go1 과 go2 를 멤버로 잡아야하겠죠. 

아래와 같이 하면 오류가 발생합니다.  삭제 하고 나서 다시 접근하니까요.

public class TestScript : MonoBehaviour
{
    public List<GameObject> objs;
    GameObject go1;
    GameObject go2;
    void Start()
    {
        objs = new List<GameObject>();
        GameObject go1 = new GameObject();
        go1.name = "go1";

        GameObject go2 = new GameObject();
        go2.name = "go2";
        objs.Add(go1);


        Destroy(go1);
        print(go1.name);
    }

    // Update is called once per frame
    void Update()
    {
        print(go1.name);
    }
}

Hyobin Kim님의 프로필

Hyobin Kim

질문자

2021.05.08

이게 라이프 사이클이랑 관련 있을거라고는 생각을 못했네요

어쨋거나 한 프레임에서 일어나는 거니까 Start()함수가 실행된 바로 그 프레임에서 만들고, 추가하고 지우고 그리고 다시 접근하는 이 모든게 다 일어나는 거라 생각했습니다

그렇다면, 메모리 인스턴스의 새로고침(?)은 프레임 단위로 일어난다고 봐도 될 까요?

네 현재 프레임이 끝나고 나서 일어납니다. 다음프레임에서는 적용되니까요.

어디서 일어나는지는 현재 프레임이 끝나고 나서 적용된다고 예상할수 있죠. 

다음프레임에 적용된다고 생각하셔도 무리 없을 것 같습니다.