작성
·
298
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);
}
}
네 현재 프레임이 끝나고 나서 일어납니다. 다음프레임에서는 적용되니까요.
어디서 일어나는지는 현재 프레임이 끝나고 나서 적용된다고 예상할수 있죠.
다음프레임에 적용된다고 생각하셔도 무리 없을 것 같습니다.
이게 라이프 사이클이랑 관련 있을거라고는 생각을 못했네요
어쨋거나 한 프레임에서 일어나는 거니까 Start()함수가 실행된 바로 그 프레임에서 만들고, 추가하고 지우고 그리고 다시 접근하는 이 모든게 다 일어나는 거라 생각했습니다
그렇다면, 메모리 인스턴스의 새로고침(?)은 프레임 단위로 일어난다고 봐도 될 까요?