GOF 패턴의 생성 패턴 중 하나로 특정 용도로 객체를 하나만 생성한 뒤, 공용으로 사용하고 싶을 때 사용하는 디자인 패턴
즉, 인스턴스가 하나만 존재하는 것을 보증하고 싶을 경우
에 사용합니다.
쉽게 말해서 클래스에 대한 Instance는 최초 생성될 때 딱 한번만 생성해서 전역에 두고, 그 이후로는 이 Instance만 접근 가능하게 하는 방법이 바로 싱글톤 패턴이에요.
주로 환경설정
, 네트워크 객체
, 로그인 정보
등을 특정 용도로 생성해둔 객체에 넣어두고 필요할 때마다 여러 객체에서 접근 가능하도록 하여 데이터를 사용합니다.
let sreen = UIScreen.main
let userDefaults = UserDefaults.standard
let application = UIApplication.shared
let fileManager = FileManager.default
let notification = NotificationCenter.default
iOS개발 할 때 자주 사용하는 싱글톤 패턴들입니다!
그렇다면 이제 전역에서 Sound를 관리하는 용도의 싱글톤, SoundManager
를 한번 생성해봅시다!
프로젝트 특성상 Sound에 접근해야 하는 경우가 잦은데 매번 Play할 때마다 AVAudioPlayer 객체를 생성해 관리하는 것보다는, 싱글톤으로 필요할 때마다 Sound Resource만 바꾸어 play하는 것이 효율적이라고 판단했어요.
final class SoundManager {
static let shared = SoundManager()
private var soundEffect: AVAudioPlayer?
var soundType: SoundType?
private init() { }
}
싱글톤의 기본적인 형태예요.
static let
으로 인스턴스 선언private
으로 선언그리고 클래스 내부에 필요한 함수들을 추가해줍니다.
func playSound(loops: Int = 0) { // enumCase에 따른 사운드 재생
var withExtension: String
switch soundType {
case .splash:
withExtension = "wav"
default:
withExtension = "mp3"
}
guard let url = Bundle.main.url(forResource: soundType?.rawValue, withExtension: withExtension) else { return }
do {
soundEffect = try AVAudioPlayer(contentsOf: url)
soundEffect?.numberOfLoops = loops
soundEffect?.play()
} catch let error {
print(error.localizedDescription)
}
}
func setVolumeFadeIn(duration: TimeInterval = 2) { // 사운드 페이드인
soundEffect?.setVolume(0, fadeDuration: duration)
}
func setVolumeFadeOut(duration: TimeInterval = 2) { // 사운드 페이드 아웃
soundEffect?.setVolume(1, fadeDuration: duration)
}
func playStoppedSound() { // 중지된 사운드 재생
soundEffect?.play()
}
func stopSound() { // 사운드 중지
soundEffect?.stop()
}
이렇게 작성하면
SoundManager.shared.soundType = .main
SoundManager.shared.playSound()
이렇게 soundType에 따라 sound를 조작할 수 있는 싱글톤이 완성됩니다.
하나의 인스턴스
만 사용하므로 메모리 낭비를 방지할 수 있습니다.전역 인스턴스
로 쉽게 데이터를 공유할 수 있습니다.싱글톤 인스턴스
가 너무 많은 일을 하거나, 많은 데이터를 공유시킬 경우 다른 클래스의 Instance들 간 결합도가 높아져 개방-폐쇄 원칙을 위배
Thread Safe
란 여러 스레드에서 어떤 객체에 대해 동시에 접근이 이루어져도 프로그램의 동작에 이상이 없는 것을 뜻합니다.
만약 멀티 스레드 환경에서 동시에 싱글톤을 사용하는 경우 인스턴스가 2개 이상 생성되는 Thread Unsafe한 경우가 생길 수 있습니다!
이를 방지하고자 Objective-C에서는 dispatch_once_t
를 사용하여 인스턴스가 1회만 생성된다는 것을 보장합니다.
하지만 swift는 static let
으로 선언하는 것만으로도 1회 생성을 보장한다고 합니다!
아주 간편하군요! 그러나 싱글톤은 앞서 말했듯이 안티 패턴이라 불릴 정도로 단점도 가지고 있기에 적절한 상황에서 사용하면 좋을 것 같습니다.