안녕하세요 :) 소들입니다
이번 포스팅에선 싱글톤 패턴이 무엇이고,
Swift에선 어떻게 사용되는지에 대해 알아보려고 해요!!!
왜 네트워크 하다가 갑자기 SingleTon이냐 하면
내 마음임
모든 포스팅은 편의 말투로 합니다~!!
1. Singleton Pattern이란?
싱글톤 패턴이란,
특정 용도로 객체를 하나만 생성하여,
공용으로 사용하고 싶을 때 사용하는 디자인 유형
음 이 말만 봐선 이해가 안 갈 거 같은데, 예제로 보여주겠음 :)
내가 만약 내가 다음과 같은 User의 정보를 저장하는 클래스를 만들었음
class UserInfo {
var id: String?
var password: String?
var name: String?
}
|
그리고 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 id: String?
var password: String?
var name: String?
}
|
먼저 전역으로 저장될 것이니,
static을 이용해 Instance를 저장할 프로퍼티를 하나 생성해주셈
2-2. init 함수 접근제어자를 private로 지정하기
class UserInfo {
static let shared = UserInfo()
var id: String?
var password: String?
var name: String?
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"
|
어느 클래스에서든 shared란 static 프로퍼티로 접근하면,
하나의 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 alloc] init];
});
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
|
이런 기능들에서 사용하고 있음 :)
.
.
.
참조
velog.io/@naroti/iOS-%EA%B0%9C%EB%B0%9C-Singleton-Pattern-q4k3uzgf0n
'iOS > Swift' 카테고리의 다른 글
Swift) Method Swizzling을 알아보자 (3) | 2020.12.14 |
---|---|
Swift) JSON이 도대체 뭘까 (4) | 2020.12.03 |
Swift) Codable - JSON을 쉽게 Encoding / Decoding 하자 (9) | 2020.11.30 |
Swift) Localizing - 다국어 처리하기 (16) | 2020.11.28 |
Swift 5+) String - Raw String (String 안에서 " \ 사용하기) (0) | 2020.11.11 |