봄날은 갔다. 이제 그 정신으로 공부하자

가볍게 보는 Singleton Pattern (kotlin & swift) 본문

android Tip

가볍게 보는 Singleton Pattern (kotlin & swift)

길재의 그 정신으로 공부하자 2022. 12. 5. 11:11

Singleton Pattern이란?

객체의 인스턴스가 오직 한개만 생성되는 패턴을 의미합니다.

싱글톤 패턴으로 생성된 인스턴스는 오직 한개만 생성되니 고정된 메모리 영역을 사용하기 때문에 해당 인스턴스에 접근할 때 

메모리 낭비를 방지할 수 있고 이미 생성된 인스턴스를 활용하니 속도 측면에서도 이점이 있다고 볼 수 있습니다.

하지만 가장 큰 장점은 앱의 다른 화면 또는 클래스간에 데이터 공유가 쉽다는 장점이 있습니다.

싱글톤 인스턴스가 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있기 때문 입니다.

 

싱글톤 클래스는 멀티쓰레딩 환경에서 오직 한개의 인스턴스만 생성됨을 보장해야하기 때문에 이와 관련된 처리가 필요합니다.

 

예를 들어 내정보 관리 Class를 싱글톤 패턴으로 만든다고 가정할 때 아래와 같이 만들게 되면 

class MyInfoManager {
    private var name = ""
    ...

    fun setInfo(name: Strng) {
    	self.name = name
    }

    fun getName(): String {
    	return name
    }
}

...

var myInfo1 = MyInfoManager()
var myInfo2 = MyInfoManager()
var myInfo3 = MyInfoManager()

위 코드와 같이 MyInfoManager의 인스턴스를 여러개 만들수 있기 때문에 멀티쓰레딩 환경에서 서로 잘 못된 값을 참조할 수 있는 문제가 발생합니다. 이러한 문제를 막기 위해서는 MyInfoManager의 인스턴스가 한개만 생성되도록 아래와 같이 처리할 필요가 있습니다.

 

우선 Kotlin 부터...

class MyInfoManager private constructor() {

    // singleton pattern
    companion object {
        private var instance: MyInfoManager? = null
        fun getInstance(): MyInfoManager {
            return instance ?: synchronized(this) {
                instance ?: MyInfoManager().also {
                    instance = it
                }
            }
        }
    }

    private var name = ""
    ...

    fun setInfo(name: Strng) {
	    self.name = name
    }

    fun getName(): String {
    	return name
    }
}

...

var myInfo1 = MyInfoManager.getInstance()
var myInfo2 = MyInfoManager.getInstance()
var myInfo3 = MyInfoManager.getInstance()

 

위 코드에서 MyInfoManager class는 생성자를 private를 선언했기 때문에 인스턴스를 만들기 위해서는 getInstance()를 통해 접근할 수밖에 없습니다. MyInfoManager는 synchronized 적용한 getInstance()를 통해서만 인스턴스 생성이 가능하기 때문에 유니크한 인스턴스 생성이 가능합니다. 즉 위 코드에서 생성한 3개의 myInfo 인스턴스는 모두 같은 하나의 인스턴스 입니다.

 

 

다음으로 Swift...

class MyInfoManager {
    
    // singleton pattern
    static let instance = UserStateInfoManager()
    private init() { }

    private var name = ""
    ...

    fun setInfo(name: Strng) {
	    self.name = name
    }

    fun getName(): String {
    	return name
    }
}

...

var myInfo1 = MyInfoManager.instance
var myInfo2 = MyInfoManager.instance
var myInfo3 = MyInfoManager.instance

 

앞선 코틀린 예제코드와 마찬가지로 생성한 3개의 myInfo 인스턴스는 모두 같은 하나의 인스턴스 입니다.

 

코틀린 코드와 차이점이 보이는데 코틀린과는 달리 스위프트 코드에서는 인스턴스 생성을 위한 접근자에 멀티쓰레딩 환경에서의 안정 보장을 위한 synchronized 없다는 입니다그이유는 static 사용해 타입 프로퍼티로 인스턴스를 생성하면 사용 시점에 초기화(lazy) 되기 때문에 싱글톤 인스턴스가 최초 생성되기 전까진 메모리에 올라가지 않고, Dispatch_once 자동 적용되기 때문에 코드 없이도 Instance 여러 생성되지 않는 Thread-Safe 방법을 구현할 있기 때문 입니다.

Comments