본문 바로가기
개발 블로그/아이폰개발

[iOS Swift 디자인패턴] 싱글톤 패턴(Singleton 패턴)에 대해서 알아보자..왜 사용하지?

by snapshot 2020. 5. 19.

 

싱글톤

해당 클래스의 인스턴스가 하나만 생성되는 것을 보증할 수 있는 디자인 패턴

 

위키 버전

소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다. 주로 공통된 객체를 여러 개 생성해서 사용하는 DBCP(DataBase Connection Pool)와 같은 상황에서 많이 사용된다.

싱글톤 패턴

 

 

먼저 기본적으로 싱글톤을 만드는 방법은 이렇다.

  1. 생성자는 private로 만든다.
  2. private static으로 객체 변수를 만든다.
  3. shared() 란 메서드를 만들어서 1개의 객체를 생성해서 반환하도록 한다. 

 

먼저 1. 에서 생성자를 private로 만드는 이유는 여기저기서 new 또는 alloc init으로 객체를 여러 개 만들 수 없게 하는 것이다. 

2. static으로 변수를 만드는 이유는 static 은 정적 변수로 컴파일할 때 메모리의 지정된 공간에 딱 하나만 존재하기 때문이다. 

3. shared() 란 메서드 불러 싱글톤을 사용하면 초기화가 되어 있지 않다면 초기화를 시키고 초기화가 되어 있다면 자기 자신을 반환해서 싱글톤 변수로 접근을 할 수 있게 만든다. 

 

일단 스위프트로 싱글톤 패턴의 클래스를 만들어보자. 

class Singleton {
    static let shared = Singleton() // static 변수로 자신을 반환
    private init() {}   // private 이기 때문에 다른 여기저기 new를 할 수 없다.
}

참고로 let은 상수라 thread-safe 하다. 

 

Objective C 

@interface Singletone : NSObject

+ (instancetype)sharedInstance;

@end


@implementation Singletone

+ (instancetype)sharedInstance {
    static Singletone *shared = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[Singletone alloc] init];
    });

    return shared;
}

@end

Objective c에서는  dispatch_once 이란 GCD 함수를 사용하였다.

 dispatch_once는 프로세스가 실행되는 동안 단 한 번만 실행한다는 것을 보장하기 때문에 Thead-Safe 함을 보장받을 수 있다. 

 

그런데 개발을 하다 보면 굳이 싱글톤 패턴을 사용하지 않고 static class와 static 변수, 함수로 비슷하게 구현을 할 수 있다.

왜냐면 static으로 하면 컴파일을 할 때 이미 메모리 한 공간에 자리를 잡고 있기 때문에  싱글톤처럼 사용할 수 있기 때문이다.

나 또한 싱글톤과 Static 클래스를 혼용해서 사용한 적이 있다.

 

그렇다면 싱글톤은 왜 사용할까..? 

lazy 로딩으로 굳이 사용하지 않을 때 메모리를 사용을 줄일 수 있다.

또 다른 이유는 좀 더 찾아봐야겠다. 

 

 

왜 사용할까?

앱 서비스

봤을 때는 세팅, 유저 정보, 로그인 등 전역에서 공통적으로 데이터를 공유할 때 사용한다. 

앱 세팅에서 전제 배경화면 변경, 다크 모드, 폰트와 같은 것을 변경할 경우 한 곳에서 변경을 하면 다른 부분도 공통적으로 변경을 해야 하기 때문에 싱글톤 패턴이 괜찮을 것이다.

사용자 정보의 경우도 순간순간 바뀌지는 않지만 유저의 닉네임, 프로필 사진과 같은 경우는 각 화면마다 각자 사용하는 게 아니기 때문이다. 로그인과 로그아웃과 같은 경우에도 로그인이 필요한 화면, 필요하지 않은 화면이 있기 때문에.. 사용할 때 좋다. 

 

iOS 

의 경우 오디오, 카메라, 파일 시스템의 경우 싱글 톤으로 되어 있는 것을 우리가 사용을 하는데, 각각 객체를 생성해서 사용을 했을 때 문제는 말하지 않아도 알 것이다. 소리 조절을 마음대로, 또는 겹치는 문제, 파일을 겹치거나 동기화가 안 될 때.... 끔찍하다..

 

 

문제점....

싱글톤의 문제점은 글로벌하게 여기저기서 입 출력을 할 수 있기 때문에  멀티스레드상에서 Thread-safe 하지가 않다. 하나의 원본에 여러 스레드들이 동시다발적으로 사용이 가능하다. 

 

해결 방법은 GCD에서 barrier를 넣어 사용을 한다. 

https://popopo.tistory.com/181?category=821251

 

[iOS GCD(Grand Central Dispatch)] 기본 2 단계

이제 실제 GCD를 사용하는 방법 및 주의사항을 설명해보도록 할게요. let sirialQueue = DispatchQueue(label: "free") // sirialQueue create let sirialQueue01 = DispatchQueue(label: "free") // sirialQueue0..

blog.lovenfree.com

 

댓글