I don’t get it with the `IncorrectDereferenceExcep...
# kotlin-native
p
I don’t get it with the
IncorrectDereferenceException
It seems I cant use kotlin native on a background thread at all. (kotlin 1.4.21 and coroutines 1.4.2-native-mt)
Copy code
import platform.darwin.DISPATCH_QUEUE_PRIORITY_DEFAULT
import platform.darwin.dispatch_async
import platform.darwin.dispatch_get_global_queue
import platform.posix.sleep
import kotlin.test.Test

class PersonGenerator

class MyTest {
  
  @Test
  fun test() {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.toLong(), 0)) {
      PersonGenerator()
    }
    sleep(1000)
  }
}
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared MyTest.$test$lambda-0$FUNCTION_REFERENCE$43@8ae08b08 from other thread
t
You need to freeze the lambda
p
Oh you are right!
And can I freeze things from swift?
Can they create kotlin class x on thread a and access it's function y on thread b?
t
I have not tried freezing objects from Swift code so I am not sure if that is possible or if the freeze function is visible in Swift
I also think you need to call
initRuntimeIfNeeded()
in the lambda
p
Big that assumption is right that I need to freeze the instance if I want to call it's function like in the scenario?
And freeze has nothing to do with Java immutability?
I would need to freeze a data class Person(val age : Int) instance as well?
t
If you are passing Kotlin classes between threads using dispatch_async, yes you need to freeze manually
If you are using Coroutines then classes are automatically frozen if needed
p
So I could just call freeze in the init block as well?
t
If you do not have subclasses or initialise variables after the init block that should work
With Coroutines you do not need to call freeze as classes are automatically frozen. That way you do not need to freeze everything manually. https://github.com/Kotlin/kotlinx.coroutines/blob/native-mt/kotlin-native-sharing.md
If you capture a reference to any object that is defined in the main thread outside of 
withContext
 into the block inside 
withContext
 then it gets automatically frozen for transfer from the main thread to the background thread.
b
in that example:
Copy code
val work = { PersonGenerator() }.freeze()
might work
(might need to type that as () -> Unit though)
p
@Kai Limadjaja cc
👀 1
Thanks everyone 🙂
Okay but that effectively means that ios can’t create kotlin objects on a non main thread? oO
t
Please explain, of course you can create objects on different threads.
p
Then why is my example crashing?
t
The example above? You need to freeze the lambda
This should work:
Copy code
import platform.darwin.DISPATCH_QUEUE_PRIORITY_DEFAULT
import platform.darwin.dispatch_async
import platform.darwin.dispatch_get_global_queue
import platform.posix.sleep
import kotlin.test.Test

class PersonGenerator

class MyTest {
  
  @Test
  fun test() {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.toLong(), 0), {
      PersonGenerator()
    }.freeze())
    sleep(1000)
  }
}
p
Okay slowly I'm understanding it. But that still means that I would need to create some freeze function that I can use when they want to functions on classes they created on different threads?