Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin/Native: Can someone help me in suggesting how to create a frozen singleton that takes in init parameters?

Below code will not work because companion object will be created and made immutable as soon as we try to access it like SomeClass.getInstance() or any other property of it and I won't be able to initialise someClass property. I want it to be immutable/frozen (because this will be accessed from multiple threads) but I can't do it when it takes parameters.

Any suggestions?

actual open class SomeClass private constructor(private val someProperty: SomeProperty) {
    actual companion object {
        private var someClass: SomeClass? = null
        fun initialize(someProperty: SomeProperty){
            someClass = SomeClass(someProperty)
        }
        actual fun getInstance(): SomeClass {
            if (someClass == null) {
                throw UninitializedPropertyAccessException("SomeClass is not initialised yet")
            }
            return someClass as SomeClass
        }
    }
}

One possible solution is to use AtomicReference here. Like so:

actual open class SomeClass private constructor(private val someProperty: SomeProperty) {
    actual companion object {
        private var someClassAtomicRef: AtomicReference<SomeClass?> = AtomicReference(null)
        fun initialize(someProperty: SomeProperty){
            val someClass = SomeClass(someProperty)
            someClassAtomicRef.value = someClass.freeze()
        }
        actual fun getInstance(): SomeClass {
            return someClassAtomicRef.value ?: throw UninitializedPropertyAccessException("SomeClass is not initialised yet")
        }
    }
}

The problem with above code is that I can call SomeClass.initialise again and have another instance of SomeClass in AtomicReference.

Is there a better way to achieve this?

like image 433
kerry Avatar asked Dec 22 '25 03:12

kerry


1 Answers

Atomic Reference is the way to go here

actual open class SomeClass private constructor(private val someProperty: SomeProperty) {
    actual companion object {
        private var someClassAtomicRef: AtomicReference<SomeClass?> = AtomicReference(null)
        fun initialize(someProperty: SomeProperty){
            val someClass = SomeClass(someProperty)
            someClassAtomicRef.compareAndSet(null, someClass.freeze())
        }
        actual fun getInstance(): SomeClass {
            return someClassAtomicRef.value ?: throw UninitializedPropertyAccessException("SomeClass is not initialised yet")
        }
    }
}
like image 85
kerry Avatar answered Dec 23 '25 17:12

kerry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!