TIL

2024 10 22 TIL (싱글톤, 프로퍼티)

noc777 2024. 10. 22. 21:03

싱글톤에 대해 막연히 용도에 맞게 쓰려고만 하였지 제대로 이해하였다 생각하지 않기에 

검색과 질문을 통해 생각을 정리해 보려하였다.

 

먼저 유니티에서 싱글톤을 쓰는 이유는 MonoBehavior 을 상속받는 클래스를 new 키워드로 인스턴스를 생성할 수 없기 때문에 전역변수(static)을 활용하여 객체(class)에서 직접 멤버를 끌어쓰는 것으로 알고 있다. 

 

이것만으로는 이해하기가 힘들었기에 좀 더 파고들어 키워드 별로 검색을 해보았다.

 

먼저 객체

 

객체는 동일한 목적이나 기능을 하는 변수나 함수들을 각각 하나로 묶은 것을 정의한다라고 합나다.

 

그리고 클래스(class)는 객체를 정의해 놓은 틀 , 설계도라고 생각합니다.  즉 객체는 기능  클래스는 기능을 활용하기 위한 수단입니다. 클래스안에 객체를 모아놓았다고 생각하시면 되겠습니다.

 

인스턴스는  이 클래스로 생성된 객체입니다. 흔히 클래스의 객체라고 부른다면 그것은 인스턴스입니다.

이 인스턴스는 객체 원본이 아닌 클래스로 복제된 새로운 객체라고 보면 되겠습니다.

 

여기서 전역 키워드 static을 살펴보자면 static은 움직이지 않는다는 뜻입니다. 그래서 정적 키워드라고도 하죠

C# 에서 이용하는 static 키워드를 사용한 멤버변수나 메소드는  클래스를 통해 인스턴스를 만들더라도 

인스턴스에 복제되지 않고 원본 클래스에 남아있습니다.  따로 인스턴스를 만들어 가져올 필요없이 그대로 클래스의

경로를 따라가 멤버에 접근이 가능하다는 것입니다.

 

new 키워드는 객체(인스턴스)를 새로 복사하여 생성한다는 것입니다. 가끔 콘솔창에서 new 키워드는 원본을 숨긴다라고

표현할 때가 있는데 그것의 의미는 원본을 숨기고 새로 원본을 복제하였다라는 뜻일겁니다.

따라서 생성된다는 개념으로 new 키워드를 사용해 생성자라는 메서드를 사용할 수 도 있다고 알아두면 될 것 같습니다.

 

이제 이 개념들을 가지고 싱글톤을 살펴보겠습니다. 

싱글톤을 사용하는 용도는 따로 인스턴스를 만들지않고 멤버에 접근하고 싶을 때 사용합니다. 

public class Manager : MonoBehaviour
{
    private static Manager instance; 

    public static manager Instance 
    {
        get    
        {
            if (instance == null) 
            {
                instance = FindObjectOfType<Manager>(); 

                if (instance == null)  
                {
                    GameObject obj = new GameObject(nameof(Manager));
                    instance = obj.AddComponent<Manager>(); 
                }
            }
            return instance; 
        }
    }
}

 

이것은 프로퍼티를 사용한 싱글톤의 예제입니다. 일단 하나씩 살펴보도록 합니다.

private static Manager instance;  //선언만 되었기에 현재 Null 값을 가지고 있다.

 

먼저 프로퍼티를 사용하기 위해 지정자는 private

클래스 자기자신의 타입인 Manager  의  instance 를 생성한다.

 

여기서 static을 선언해주었기에 인스턴스로는 복제가 되지 않는다.

 

public static manager Instance 
    {
        get    
        {
        }

다음은 프로퍼티를 생성할 것이다.  만약 외부에서 Manager의 멤버를 가져오고 싶다면 Instance를 통해 가져오게 하기 위해 get에 설정을 해준다.

 

public static manager Instance 
    {
        get    //불러올 때만 실행된다.
        {
            if (instance == null) //만약 instance 가 Null이라면
            {
                instance = FindObjectOfType<Manager>();  //일단 먼저 Manager 타입인 오브젝트를 찾아보고 instance 에 대입

                if (instance == null)  //그럼에도 null이라면
                {
                    GameObject obj = new GameObject(nameof(Manager));
                    //새로 게임오브젝트를 생성해준다.
                    //new 키워드로 게임 오브젝트를 생성하는데 이름이 Manager인 오브젝트를 생성한다.
                    //그러고나서 생성한 오브젝트에 대입하여 초기화를 완료시킨다.
                    instance = obj.AddComponent<Manager>(); 
                    //생성한 오브젝트에 AddComponent를 통해 Manager 타입을 부여하고 null인 instance에 대입
                }
            }
            return instance; //위에서 처리된 과정을 통해 만들어진 instance를 외부에 반환
        }

 

 

프로퍼티 조건에 instance 값이 null일 때를 상정하고 안에 instance의 값을 부여한다.

 

awake()
{
  if(instance == null) //instance 값이 null 이라면
      instance = this;  //이 게임오브젝트 ( instance가 되는 해당클래스) 가 instance에 대입
  else  //null이 아니라면
      Destroy(gameobject) // 이 게임 오브젝트가 삭제된다. (씬이 변경되는 등의 상황)
}

그리고 일반적인 프로퍼티의 설정로직

'TIL' 카테고리의 다른 글

2024 10 24 TIL  (0) 2024.10.24
2024 10 23 TIL  (0) 2024.10.23
2024 10 21 TIL  (0) 2024.10.21
2024 10 18 TIL  (0) 2024.10.18
2024 10 17 TIL  (0) 2024.10.17