[Swift] 싱글톤 패턴 (Singleton Pattern)
[Swift] 싱글톤 패턴 (Singleton Pattern)
싱글톤 패턴이란, 특정 용도로 객체를 하나만 생성하여 공용으로 사용하고 싶을 때 사용하는 디자인 패턴입니다.
클래스가 여러차례 호출되더라도, 인스턴스는 딱 한번만 생성되게 하는 것입니다. 이렇게 되면 전역변수처럼 코드의 어느 곳에서 접근하던 간에 같은 메모리에 접근이 가능해집니다.
예제
사용자의 정보를 저장하는 UserInfo
라는 클래스를 만들고 A, B, C 라는 3개의 ViewController 가 있다고 가정해보겠습니다.
A 에서는 사용자의 이름을, B 에서는 사용자의 전화번호를, C 에서는 사용자의 주소를 추가하기 위해 각각 UserInfo
인스턴스를 생성하여 값을 넣어주었습니다.
하지만 이렇게 된다면 A, B, C 에서 각각 인스턴스를 하나씩 총 3개 생성하기 때문에 인스턴스들은 모두 다른 메모리를 가리키게 됩니다. 이를 싱글톤 패턴을 이용하여 수정해보도록 하겠습니다.
위의 코드와 달라진 점은, static let
프로퍼티가 추가되었고, private init()
생성자가 추가되었다는 점입니다. 이 때문에 인스턴스는 외부에서 재생성될 수 없습니다.
shared
프로퍼티는 static
으로 선언되었기 때문에 프로그램이 실행될 때 메모리에 올라가고, 그에 따라 UserInfo
인스턴스가 딱 1번 생성됩니다. 또한 let
으로 선언되었기 때문에 인스턴스 자체를 변경할수도 없습니다.
이를 이용하면 코드의 userInfo.shared
와 같이 프로퍼티를 이용한 구문으로 생성된 인스턴스에 접근할 수 있게 됩니다. 이는 코드의 어느 부분에서나 접근 가능하며 static
으로 선언되었기 때문에 인스턴스 내부의 프로퍼티 값을 공유합니다.
또한 생성자가 private
으로 선언되었기 때문에 외부에서 생성자를 다시 호출하여 인스턴스를 재생성하는 것을 방지할 수 있습니다.
장단점
장점
- 인스턴스가 1번만 생성되기 때문에 메모리 낭비를 방지할 수 있다
- 전역 인스턴스로 사용할 수 있기 때문에 메모리 및 자원 관리가 쉽다
- 메모리를 할당하고 초기화하는 시간이 줄어들어 객체 접근 시간이 줄어든다
단점
- 생성자가
private
이기 때문에 Mock 객체를 만들어내기 어려워 테스트가 힘들다 - 어느곳에서나 쉽게 접근이 가능해 의존성이 생긴다
- 멀티 스레드 환경에서 객체가 2개 생성되는 위험이 발생할수 있다
멀티 스레드 문제
위의 단점에서 언급한것과 같이, 싱글톤 객체는 딱 한번만 생성되어야 하는데 멀티스레드 환경에서 클래스에 동시에 접근할 시 객체가 2개 생성되는 위험이 발생할 수 있습니다. 이는 Thread-Safe 를 보장하지 않습니다.
Objective-C 에서는 싱글톤을 생성할때 dispatch_once
를 이용해 객체가 단 한번만 불리게 하지만 Swift 에서는 static let
으로 선언하는 것 만으로 1회 생성을 보장받습니다.
그렇기 때문에 저희는 쉽게 싱글톤 객체를 생성하여 사용할 수 있습니다.
사용 예제
저희가 신경쓰지 않고 무심코 지나치는 부분에서도 싱글톤은 쓰이고 있습니다. 예로 몇가지를 들자면
UIScreen.main
URLSession.shared
NotificationCenter.default
UserDefaults.standard
등에서 싱글톤이 사용되는 것을 확인할 수 있습니다.
참고 링크
https://babbab2.tistory.com/66
https://dvlpr-chan.tistory.com/36