Imtiaz Abbas
Imtiaz Abbas

Reputation: 52

Unable to pass swift implementation of kotlin interface to kotlin native

I have an interface SampleInterface in CommonMain

interface SampleInterface {
  fun printMessage(message: String)
}

and a singleton object Singleton in CommonMain

object Singleton {
  private var interfaceObj: SampleInterface? = null
  fun setup(interfaceObj: SampleInterface) {
    this.interfaceObj = interfaceObj
  }

  fun printMessage(message: String) {
    this.interfaceObj?.printMessage(message)
  }
}

I am trying to Implement the interface SampleInterface in swift

class IosImpl: SampleInterface {
  func printMessage(message: String) {
    print("\(message)")
  }
}

passing the IosImpl object from swift to Singleton in kotlin native

func test() {
  let iImpl = IosImpl()
  Singleton().setup(iImpl) // Failing with KotlinException
}

Exception:

Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen 

Upvotes: 0

Views: 1175

Answers (1)

Artyom Degtyarev
Artyom Degtyarev

Reputation: 2888

The problem here is the result of trying to mutate Kotlin's singleton.
In Kotlin/Native, there are strict immutability rules, and one of them states that every object is mutable XOR shared. To achieve this, for singleton objects and enums are "frozen" by default - this means every attempt to mutate them will finish with InvalidMutabilityException, as you got. To avoid this, one got to make sure that object is thread-local and will never be mutated from another thread.
To read more on this theme, I recommend you to take a look at Immutability description on the K/N Github, and also the Concurrency one.

Upvotes: 2

Related Questions