【问题标题】:How can I freeze Kotlin objects created in Swift?如何冻结在 Swift 中创建的 Kotlin 对象?
【发布时间】:2020-12-01 14:15:59
【问题描述】:

我正在使用带有 native-mt 协程支持和 Ktor 库的 Kotlin-Native。我有几个暂停的函数,它们接收使用构建器模式构建的对象。我知道我需要在 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.ktfreeze() Kotlin 函数似乎无法从导入我的库的 Swift 代码?冻结仅适用于 iOS 代码这一事实使情况更加复杂,因为 Android 代码不需要它。

有没有更简单的方法将 Swift 创建的 Kotlin 对象传递给挂起的函数,而不需要在主线程上创建这些对象?

【问题讨论】:

    标签: swift kotlin kotlin-coroutines kotlin-multiplatform


    【解决方案1】:

    在 Kotlin/Native 世界中,每当您在线程之间共享对象时,如果您不打算将它们设为 @ThreadLocal,则必须确保它们被冻结(不可变)。 Android 是个例外,因为 JVM 没有那么严格,让我们在线程之间共享可变对象。

    你有两个选择:

    1. 要么公开 freeze() 函数并使用它
    2. freeze() 共享代码中的每个传入对象

    另外,如果你不冻结,你可能会碰到IncorrectDereferenceException,这意味着你正在尝试共享可变/非冻结状态

    【讨论】:

    • 对于选项 2,这是否意味着,实际上,如果 Swift 接收到我无法保证被冻结的对象,我就无法从 Swift 中调用挂起的函数?
    【解决方案2】:

    你不会冻结 Swift 类。如果 CustomerQuery 是 Kotlin 类,则需要冻结它。

    但是,如果您依赖 Kotlin 编译器自动生成的 Objc 接口,则只需在主线程上调用挂起函数。我们通常建议不要这样做,因为您无法控制生命周期,但这是完全不同的讨论。

    【讨论】:

    • 是的,我知道你不会冻结 Swift 类。由于挂起的函数正在接收对象,因此它必须是 Kotlin 类。从 Swift 调用挂起函数时,使用 objc 接口的更好选择是什么?
    • 好吧,如果 CustomerQuery 符合 Kotlin 接口,您可以将其传入。但是,CustomerQuery 似乎是一个 Kotlin 类,在这种情况下,它需要被冻结并且纳吉的回答有更多选择。挂起的替代方法是编写一个管理协程范围的本机接口。更多工作,但您可以控制生命周期:github.com/touchlab/KaMPKit/blob/master/shared/src/iosMain/…
    • 好的,谢谢 - 这就是我所害怕的。
    猜你喜欢
    • 2013-11-10
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多