我使用的是Kotlin-Native和原生mt协程支持和Ktor库。我有几个挂起的函数,它们接受一个使用构建器模式构建的对象。我知道我需要在main/ui线程上调用挂起的函数。但是,我不能保证构建器对象将在该线程上创建。我的理解是,在将它们发送到主线程以使用挂起的函数调用之前,它们需要被冻结。对吗?
例如,这将失败,因为查询对象尚未冻结:
func loadData() {
DispatchQueue.global(qos: .background).async {
let query = CustomerQuery().emails(value: ["customer@gmail.com"])
self.fetchCustomersAndDoSomething(query: query)
}
}
func fetchCustomersAndDoSomething(query: CustomerQuery) {
DispatchQueue.main.async {
self.mylibrary.getCustomers(query: query) { response, err in
// do something with response
}
}
}如果这是真的,我需要为每个这样的对象添加一个方法来“冻结”它,这是正确的吗?因为从Freezing.kt导入我的库的freeze()代码似乎不能访问Swift Kotlin函数?冻结只适用于iOS代码,因为Android代码不需要它,这一事实使情况变得更加复杂。
有没有一种更简单的方法来将Swift创建的Kotlin对象传递给挂起的函数,而不需要在主线程上创建这些对象?
发布于 2020-12-01 23:14:27
在Kotlin/原生世界中,当你在线程之间共享对象时,如果你不打算让它们成为@ThreadLocal,你必须确保它们是冻结的(不可变的)。Android是个例外,因为JVM并不那么严格,让我们在线程之间共享可变对象。
您有两个选择:
freeze()函数,并使用共享代码中的每个传入对象
另外,如果你不冻结,你可能会碰到IncorrectDereferenceException,这意味着你正在尝试共享可变/非冻结状态
发布于 2020-12-01 23:43:56
你不会冻结Swift类。如果CustomerQuery是一个Kotlin类,你需要冻结它。
但是,如果依赖于Kotlin编译器自动生成的Objc接口,则只需要在主线程上调用挂起函数。我们通常不建议这样做,因为您无法控制生命周期,但这是一个完全不同的讨论。
https://stackoverflow.com/questions/65092211
复制相似问题