2014년 6월 14일 토요일

Swift - 싱글톤 패턴(Singleton Pattern)

싱글톤 패턴(Singleton Pattern)은 단 하나의 인스턴스(객체 혹은 오브젝트)를 만들어 두고 이를 여러 곳에서 쉽게 액세스 할 수 있게 하는것이 목적이다. 그래서 이 하나의 인스턴스만을 생성하고 쉽게 얻을 수 있게 하는 팩토리 패턴을 만드는 것이 싱글톤 패턴의 목적이다.

[참고] 이 글은 Objective-C의 싱글턴 패턴과 비슷한 dispatch_once를 활용한 글이다. Swift 에서는 이 보다 더 쉬운 방법으로도 안전한 싱글턴 패턴을 구현 할 수 있다. 아래 링크를 참고하자.

[Swift] 좀 더 단순한 싱글턴 패턴(Singleton Pattern)

일반적으로 쓸 만한 스위프트(Swift)용 싱글톤 패턴은 아래와 같은 식이다.
class SingletonClass {
    struct StaticInstance {
        static var dispatchToken: dispatch_once_t = 0
        static var instance: SingletonClass?
    }
    
    class func sharedInstance() -> SingletonClass {
        dispatch_once(&StaticInstance. dispatchToken) {
            StaticInstance.instance = SingletonClass()
        }
        return StaticInstance.instance!
    }
}
sharedInstance() 라는 타입메소드가 싱글톤의 팩토리 메소드이다. Objective-C로 싱글톤을 만드는 코드와 비슷하긴 한데 클래스에서 static 키워드를 사용 할 수 없는 제약과 dispatch_once 사용으로 인해 좀 복잡하게 구현되어 있다.

설명을 위해 조금 더 단순하게 바꾼 예제를 보자.
class SimpleSingletonClass {
    struct StaticInstance {
        static var instance: SingletonClass?
    }
    
    class func sharedInstance() -> SingletonClass {
        if !StaticInstance.instance {
            StaticInstance.instance = SingletonClass()
        }
        return StaticInstance.instance!
    }
}
앞서 본 코드와 동일한 역활이지만 dispatch_once 라는 thread-safe를 위한 기능이 제거된 코드이다.

스위프트에서는 클래스 내부에서 정적인 선언, 즉 static 사용이 불가능하다. 그래서 이를 대체하기 위해 정적 프로퍼티를 가지는 구조체 StaticInstance 를 내부에서 선언했다. 이렇게 해서 우회적으로 static 사용이 가능해진다.

나머지는 StaticInstance의 정적 프로퍼티 .instance를 이용해 이 값이 생성 안되어 있으면 자신의 클래스 인스턴스를 만들어서 할당한다. 그리고 리턴시킨다. 따라서 StaticInstance에 보관된 .instance가 실제로 사용할 클래스 인스턴스가 만들어지는 곳이고 sharedInstance() 메소드는 이 값을 리턴시키는 것이 목적이다.

이 축약된 예제도 완벽하게 싱글톤 형태로 동작한다. 만약 멀티스레드를 사용하지 않는다면 이 정도로도 충분한 싱글턴 패턴이 완성된다.

하지만 멀티스레드 환경에서는 문제의 소지가 있다. sharedInstance() 라는 타입메소드가 만약 여러 스레드에 의해 한번에 호출될 경우 인스턴스가 하나만 생성된다는 보장이 없다. 따라서 가급적이면 단 한번의 인스턴스 생성이 보장되는 dispatch_once를 사용하는 제일 위의 싱글톤 패턴을 사용하길 추천한다.

[관련글] Swift - 클래스(Class) 훑어보기
[관련글] Swift - 프로퍼티(Properties)
[관련글] Swift - 메소드(Method)
[관련글] Objective-C Singleton Pattern

댓글 없음 :