Вызов класса в swift из kotlin / native framework

#kotlin

#kotlin

Вопрос:

Я следовал руководству:https://kotlinlang.org/docs/tutorials/native/mpp-ios-android.html и успешно экспортируем jar-файл для Android и фреймворк для iOS. После я хочу реализовать что-то более сложное. Я использую Android Studio Kotlin с приведенными ниже кодами:

Model.kt:

 package org.kotlin.mpp.mobile.BusinessLogic

abstract class Model{

var _id:Long = 0

abstract fun PolymorphismTest()
}
  

Sales.kt:

 package org.kotlin.mpp.mobile.BusinessLogic

class Sales : Model() {

init {
    this._id = _counter
    _counter  

}
companion object {

    private var _counter: Long = 0

}

fun get_counter(): Long {
    return _counter
}

private val _salesItems:MutableList<SalesItem> = ArrayList()

fun SalesItems(): MutableList<SalesItem> {
    return _salesItems
}

fun TotalAmount():Double
{
    var totalAmount:Double = 0.0
    for(aSalesItem in _salesItems)
    {
        totalAmount  = aSalesItem.SubTotal()
    }

    return totalAmount
}

fun AddSalesItem(salesItem: SalesItem)
{
    this._salesItems.add(salesItem)
}

fun AddSalesItem(itemName:String, itemCode:String, quantity:Double, amount:Double )
{
    val aSalesItem = SalesItem()
    aSalesItem._itemCode = itemCode
    aSalesItem._itemName = itemName
    aSalesItem._quantity = quantity
    aSalesItem._amount = amount
    this.AddSalesItem(aSalesItem)
}

fun ToString(): String {
    return "Sales: $this._id"
}


override fun PolymorphismTest() {
    println("This is method from Sales")
}

}
  

SalesItem.kt:

 package org.kotlin.mpp.mobile.BusinessLogic

class SalesItem : Model() {

init {
    this._id = _counter
    _counter  
}
companion object {

    private var _counter: Long = 0
}

fun get_counter(): Long {
    return _counter
}

var _sales: Sales? = null

var _amount:Double = 0.toDouble()
var _quantity:Double = 0.toDouble()

fun SubTotal(): Double {
    return _amount * _quantity
}

var _itemName:String? = null
var _itemCode:String? = null


fun Sales():Sales?{
    return _sales
}

fun SalesItem(sales:Sales)
{
    _sales = sales
    this._id = _counter
    _counter  
}

fun ToString(): String {
    return "Sales: $this._id"
}

override fun PolymorphismTest() {
    println("This is method from SalesItem")
}
}
  

Я экспортирую эти коды в фреймворк, затем импортирую в Xcode и использую Swift для вызова

ViewController.swift

 import UIKit
import SharedCode
class ViewController: UIViewController{

override func viewDidLoad(){
     super.viewDidLoad()

     print("Creating Sales Object")
     let sales = Sales() //error here

   }
 }
  

После этого я столкнулся с ошибками

Экземпляры kotlin.Ошибка, исключение kotlin.RuntimeException и подклассы не передаются из Kotlin в Objective-C / Swift. Другие исключения могут распространяться как NSError, если метод имеет аннотацию @Throws или наследует ее. Неперехваченное исключение Kotlin: kotlin.native.concurrent.Исключение InvalidMutabilityException: попытка мутации замороженной org.kotlin.mpp.mobile.Бизнес-логика.Продажи.Companion@228b588 с общим кодом 0

Ответ №1:

У Kotlin / Native другая модель потоков. Идея заключается в том, что экземпляр объекта должен быть заморожен, чтобы к нему можно было получить доступ из всех потоков. Для этого есть .freeze() метод расширения.

По умолчанию, object Smth также заморожены. В code sniper у вас есть изменяемые поля в сопутствующем объекте.

Возможным обходным решением может быть замена сопутствующего объекта обычным классом, который вы создаете явно

https://kotlinlang.org/docs/reference/native/concurrency.html#concurrency-in-kotlinnative

https://kotlinlang.org/docs/reference/native/immutability.html#immutability-in-kotlinnative

Комментарии:

1. удаление сопутствующего объекта, создание класса и инициализация в init или constructor устранили проблему, похоже, что сопутствующий объект не поддерживается в kotlin 1.4.10 или 1.4.0