Post

[ STUDY/유니티 ] 2023. 1. 21. 21:58

이전에 null 비교를 위한 연산으로 ==와 Equals를 보던 중 같은 기능을 수행하는  is라는 연산자를 발견하였습니다.

그럼 is란 무엇인가?

여기서 is란?

연산자로써 C#7 이전에는 객체의 타입을 체크하는 용도로 쓰였지만,

C#7 이후부터는 패턴으로써 사용할 수 있게되었습니다. 

 

패턴은 크게 상수패턴/ 타입패턴 / var 패턴으로 나뉘어져있고

여기서 이번 게시물과 밀접한 관련이 있는 패턴은 상수패턴입니다.

 

상수패턴은 특정 상수값을 사용해 패턴을 체크함으로써 ==과 같은 기능을 합니다.

(instance is null 과 instance==null은 같게 결과가 나옴.. 처럼 보이지만 내막이 있는데...)

 

하지만 기능이 같다고 아예 같다란 것은 아닙니다.

제가 본 글들은 is가 ==보다 속도면에서 우수하다고 하는데

그 이유를 제가 자세히 몰라  왜 그런걸까 한번 알아봤습니다.


먼저, 유니티에는 두가지 오브젝트가 있습니다.

 

하나는 System.Object이고, 다른 하나는 UnityEngine.Object입니다.

이 두개가 나뉘는 이유는 유니티 엔진은 C++로 만들어져있습니다.

다만, 유니티에서 .NET API를 노출하여 우리는 C++대신에 C#을 이용해 개발을 할 수 있는거죠.

 

System.Object(=object)를 통해 시스템상 오브젝트(C#)를 확인하고,

UnityEngine.Object(=Object)를 통해 유니티 엔진상 오브젝트(C++)을 확인할 수 있습니다.

 

이 오브젝트들은 평소에는 신경을 쓰지 않고 개발을해도 크게 문제는 안되지만

Destroy를 할 경우 문제가 발생하게 됩니다. 

 

C++에서는 메모리를 동적할당/해제가 가능하지만, C#에서는 메모리를 사용자가 할당하고 해제할 수 없죠.
그런 상황에서 Destroy를 했을 경우에 속에 C++로 이루어진 시스템상 오브젝트는 NULL 이 되지만
C#으로 겉모습을 유지하고있는 오브젝트는 GC가 호출되어 메모리를 정리할때까지 NULL이 아니게됩니다.
유니티 엔징 상(C++)에서는  NULL이지만 시스템 상(C#)으론 NULL이 아닌 이 현상을 Fake Null이라고 합니다.


이런 Fake Null 현상을 잡아내기 위해

UnityEngine.Object 클래스에서는 같음연산자(==)를 오버로딩하여

네이티브 객체가 존재하는지 여부까지 판단하여 비교 후 결과를 돌려줍니다. 

 

하지만  is의 경우에는 (ReferenceEquals함수도 마찬가지)

실재여부 판단까지 하지않고 값만 판단하기 위해서
원시 오브젝트 자체로 비교하여 null check 비교과정을 생략하여 속도를 향상시킵니다.

 


그럼 속도가 빠른 is가 마냥 좋은걸까요?

그건 아닙니다.

 오브젝트가 Destroy가 되는 상황이 아예 없을 경우에는 is 나 ReferenceEquals가 속도면에서 좋을 수도 있지만
 그런 보장된 상황이 아니라면 좀 더 안정적으로 추가검증을 해주는 == 로 체크하는것이 좋을 것입니다.

 

무조건 빠르다고 쓰는것이 아닌

적재적소에 맞게 사용하면되는것이 결론!

 

 

 


 근데.. 솔직히..NULL체크 자주 쓰이는것도 아니라면..굳이?

 

 

 

 

 

 

▲ top