본문 바로가기

iOS/Swift

Swift) 싱글톤 패턴(Singleton Pattern)

 

 

 

안녕하세요 :) 소들입니다

이번 포스팅에선 싱글톤 패턴이 무엇이고,

Swift에선 어떻게 사용되는지에 대해 알아보려고 해요!!!

 

왜 네트워크 하다가 갑자기 SingleTon이냐 하면

내 마음임

 

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. Singleton Pattern이란?

 

싱글톤 패턴이란,

 

특정 용도로 객체를 하나만 생성하여, 

공용으로 사용하고 싶을 때 사용하는 디자인 유형

 

음 이 말만 봐선 이해가 안 갈 거 같은데, 예제로 보여주겠음 :)

내가 만약 내가 다음과 같은 User의 정보를 저장하는 클래스를 만들었음

 

 

class UserInfo {
    var idString?
    var passwordString?
    var nameString?
}

 

그리고 A ViewController에선 id를, B ViewController에선 password를,

C ViewController에선 name을 입력 받아

이를 UserInfo라는 클래스에 저장해야 한다고 생각해 보셈

 

 

//A ViewController
let userInfo = UserInfo()
userInfo.id = "Sodeul"

 

//B ViewController
let userInfo = UserInfo()
userInfo.password = "123"

 

//C ViewController
let userInfo = UserInfo()
userInfo.name = "Sodeul"

 

 

만약, 이런 식으로 A, B, C ViewController에서 각각 UserInfo 객체를 만들어서 저장하면,

 

 

 

이런 식으로 각 Instance의 프로퍼티에만 저장될 것이고 😱

이는, 우리가 원하는 그림이 아닐 것이란 말임???

한 Instance에 모든 정보가 저장되어야 하는데...!!

 

그럼 방법이 하나 더 있긴 함

인스턴스는 참조 타입이기 때문에, User Info 인스턴스를 한번 생성한 후,

이 인스턴스를 A->B->C로 필요할 때마다 참조로 넘겨줄 수도 있긴 함

 

근데 이렇게 해도 되지만,

App 어디 클래스든 User Info 인스턴스가 참조되어야 할 때마다

매번 이 인스턴스를 넘겨주기도 귀찮고...... 코드도 지저분해져... 😱

따라서

 

 이 클래스에 대한 Instance는 최초 생성될 때 딱 한번만 생성해서 전역에 두고,

그 이후로는 이 Instance만 접근 가능하게 하자

 

는게 바로 Singleton Pattern임!!!!

따라서 싱글톤을 사용하면 다음과 같은 그림이 됨

 

 

 

이런 식으로 한 Instance어디 클래스에서든 접근 가능하게 하는 것임!

커엽 👀

 

 

 

 

2. Singleton Class 만드는 방법

 

Swift에선 매우매우매우매우 간단하다

(Objective-C는 Dispatch_once 막 이런 거 썼었는데 Swift는 세상 간편하다)

 

 

 

2-1. static 프로퍼티로 Instance 생성하기

 

 

class UserInfo {
    static let shared = UserInfo()

    var idString?
    var passwordString?
    var nameString?
}

 

먼저 전역으로 저장될 것이니,

static을 이용해 Instance를 저장할 프로퍼티를 하나 생성해주셈

 

 

 

2-2. init 함수 접근제어자를 private로 지정하기

 

class UserInfo {
    static let shared = UserInfo()

    var idString?
    var passwordString?
    var nameString?

    private init() { }
}

 

혹시라도 Init 함수를 호출해 Instance를 또 생생하는 것을 막기 위해,

init() 함수 접근 제어자를 private로 지정해주면 됨 ㅎㅎ

 

 

자 그럼 Swift로 Singleton 만들기 끝!!!!!!!

그럼 외부에서 어떻게 접근하냐?

 

 

 

3. Singleton Class 접근하는 방법

 

이또한 매우 간단쓰..

아까 생성해뒀던 static 프로퍼티를 이용하면 됨

 

 

//A ViewController
let userInfo = UserInfo.shared
userInfo.id = "Sodeul"

 

//B ViewController
let userInfo = UserInfo.shared
userInfo.password = "123"

 

//C ViewController
let userInfo = UserInfo.shared
userInfo.name = "Sodeul"

 

 

어느 클래스에서든 sharedstatic 프로퍼티로 접근하면,

하나의 Instance를 공유하는 것임 :)

 

 

 

 

4. Singleton의 장단점

 

그럼 Singleton의 장점, 단점이 뭔지 알아보자!!!

 

장점 - 한 번의 Instance만 생성하므로 메모리 낭비를 방지할 수 있음
- Singleton Instance는 전역 Instance로 다른 클래스들과 자원 공유가 쉬움
- DBCP(DataBase Connection Pool)처럼 공통된 객체를 여러개 생성해서 사용해야하는 상황에서 많이 사용 (쓰레드풀, 캐시, 대화상자, 사용자 설정, 레지스트리 설정, 로그 기록 객체등)
단점 - Singleton Instance가 너무 많은 일을 하거나, 많은 데이터를 공유시킬 경우 다른 클래스의 Instance들 간 결합도가 높아져  "개방=폐쇄" 원칙을 위배함 (객체 지향 설계 원칙 어긋남)
- 따라서 수정과 테스트가 어려워짐 

 

 

 

5. Swift Singleton 개짱

 

왜 Swift가 짱인지 알았다

 


The free function dispatch_once is no longer available in Swift. In Swift, you can use lazily initialized globals or static properties and get the same thread-safety and called-once guarantees as dispatch_once provided.


 

Objective-C에서 Singleton을 생성할 땐,

dispatch_once를 이용해 단 한번만 불리게 하는 작업이 있음

 

왜냐??

Java나 다른 언어에서도 마찬가지지만,

Singleton을 생성하는 것Multi Threading 환경에서 Thread-Safe하지 않기 때문

 

무슨말이냐면, 

여러 쓰레드가 만약 동시에 Singleton을 생성하면,

경우에 따라 Instance가 2개 3개 생성될 수도 있었음

 

따라서 Objective-C에서도, App이 실행되고 단 한번만 실행되게끔

dispatch_once를 사용해서 다음과 같이 Singleton을 만들었음

(java에선 LazyHolder를 사용한다 함)

 

 

@interface UserInfo : NSObject
 
+ (instancetype)sharedInstance;
 
@end
 
 
@implementation UserInfo
 
+ (instancetype)sharedInstance {
    static UserInfo *shared = nil;
 
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[UserInfo allocinit];
    });
 
    return shared;
}
 
@end

 

 

근데!!!!!!! Swift는, 위처럼 별도의 작업을 해주지 않더라도

 

static을 사용해 타입 프로퍼티로 인스턴스를 생성하면, 사용 시점에 초기화(lazy) 되잖음!?

따라서 Singleton Instance가 최초 생성되기 전까진 메모리에 올라가지 않고,

Dispatch_once도 자동 적용된다고 함!!!!

 

따라서 별 코드 없이도 Instance가 여러 개 생성되지 않는,

Thread-Safe한 방법이 되는 것임

👀 대단해..

 

+

위에서 Swift가 Thread-Safe하다고 한 것은

"싱글톤 생성"에 한정해 Thread-Safe하단 것임

 

 

 

 

 

6. iOS에선 Singleton을 언제 쓰냐면,

 

 

let screen = UIScreen.main
let userDefault = UserDefaults.standard
let application = UIApplication.shared
let fileManager = FileManager.default
let notification = NotificationCenter.default

 

 

이런 기능들에서 사용하고 있음 :)

 

 

 

 

.

.

.

참조

 

 

[swfit] thread-safety 한 싱글톤 사용은?

lazily initialized 하고 멀티코어를 고려한 Thread-Safe 방법

medium.com

velog.io/@naroti/iOS-%EA%B0%9C%EB%B0%9C-Singleton-Pattern-q4k3uzgf0n

 

[NAROTi][iOS 개발] Singleton Pattern

Singleton Pattern에 대해 알아보자 싱글톤 패턴이란 특정용도로 객체를 하나 생성하여 공용으로 사용하고 싶을 때 사용하는 방법이다. 주로 환경설정, 로그인 정보 등을 특정용도로 생성해둔 객체

velog.io

jeong-pro.tistory.com/86

 

싱글톤 패턴(Singleton pattern)을 쓰는 이유와 문제점

싱글톤 패턴(Singleton Pattern) 싱글톤 패턴 애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만들어 사용하는 디자인패턴. 생성자가 여러

jeong-pro.tistory.com

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday