Kotlin/Native - 非法尝试访问非共享 <object>

Posted

技术标签:

【中文标题】Kotlin/Native - 非法尝试访问非共享 <object>【英文标题】:Kotlin/Native - illegal attempt to access non-shared <object> 【发布时间】:2020-03-04 08:16:43 【问题描述】:

在我的应用程序中,我有两个类,一个继承自 kotlin 类的 swift 类:

Swift 类:

public class MySensor: RawSensor

    [...]

    public override func notifyChanged(values: KotlinFloatArray) 
      super.notifyChanged(values: values)
    

Kotlin 类:

package com.mycompany.myapp.mypackage.sensors.rawsensors

import com.mycompany.myapp.mypackage.util.Observable

abstract class RawSensor : Observable() 

  protected abstract val sensorDataType: RawSensorData.SensorDataType

  abstract val currentTime: Long

  protected open fun notifyChanged(values: FloatArray) 
      notifyObservers(RawSensorData(values, sensorDataType, currentTime))
  

  abstract fun start()

  abstract fun stop()

当调用super.notifyChanged(values: values) 时,应用程序崩溃并出现以下错误:

Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared <object>@83cb47c8 from other thread
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared <object>@83cb4788 from other thread
        at 0   MyNativeFramework                   0x00000001048815dc kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 84
        at 1   MyNativeFramework                   0x00000001048805f8 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 84
        at 2   MyNativeFramework                   0x00000001048ac630 kfun:kotlin.native.IncorrectDereferenceException.<init>(kotlin.String)kotlin.native.IncorrectDereferenceException + 84
        at 3   MyNativeFramework                   0x00000001048ad7bc ThrowIllegalObjectSharingException + 496
        at 4   MyNativeFramework                   0x0000000104a6f1a0 _ZNK16KRefSharedHolder3refEv + 240
        at 5   MyNativeFramework                   0x0000000104a6eeb0 -[KotlinBase retain] + 52
        at 6   libobjc.A.dylib                     0x00000001aad36288 objc_retain + 88
        at 7   PositionKit                         0x000000010449454c $s11PositionKit21MySensorC13notifyChanged6valuesySo19MyNativeLibraryKotlinFloatArrayC_tFTo + 56
        at 8   PositionKit                         0x0000000104493fa0 $s11PositionKit21MySensorC5startyyFySo19CMAccelerometerDataCSg_s5Error_pSgtcfU_ + 796
        at 9   PositionKit                         0x00000001044941ec $sSo19CMAccelerometerDataCSgs5Error_pSgIeggg_ACSo7NSErrorCSgIeyByy_TR + 152
        at 10  CoreMotion                          0x00000001b7c44a8c CLClientCreateIso6709Notation + 30848
        at 11  Foundation                          0x00000001ab3d1c60 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1170528
        at 12  Foundation                          0x00000001ab2d37e8 672CF0CB-4951-3B91-89DF-55E953AEA00F + 129000
        at 13  Foundation                          0x00000001ab3d3fbc 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1179580
        at 14  Foundation                          0x00000001ab2d3464 672CF0CB-4951-3B91-89DF-55E953AEA00F + 128100
        at 15  Foundation                          0x00000001ab3d49e8 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1182184
        at 16  Foundation                          0x00000001ab3d44a8 672CF0CB-4951-3B91-89DF-55E953AEA00F + 1180840
        at 17  libdispatch.dylib                   0x0000000104f59a48 _dispatch_block_async_invoke2 + 144
        at 18  libdispatch.dylib                   0x0000000104f4b2a8 _dispatch_client_callout + 20
        at 19  libdispatch.dylib                   0x0000000104f5935c _dispatch_main_queue_callback_4CF + 1376
        at 20  CoreFoundation                      0x00000001aaf7ce20 97285ACB-7B21-393A-ABF6-03F1DBB5D2A2 + 712224
        at 21  CoreFoundation                      0x00000001aaf77b7c 97285ACB-7B21-393A-ABF6-03F1DBB5D2A2 + 691068
        at 22  CoreFoundation                      0x00000001aaf77098 CFRunLoopRunSpecific + 480
        at 23  GraphicsServices                    0x00000001b50e1534 GSEventRunModal + 108
        at 24  UIKitCore                           0x00000001af0977ac UIApplicationMain + 1940
        at 25  MyTestApp                           0x00000001044383a4 main + 76
        at 26  libdyld.dylib                       0x00000001aadf6f30 0DC9A4BA-C3E8-3487-99DB-1B5C86597AF5 + 3888
        at 0   MyNativeFramework                   0x00000001048815dc kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 84
        at 1   MyNativeFramework                   0x00000001048805f8 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 84
        at 2   MyNativeFramework                   0x00000001048ac630 kfun:kotlin.native.IncorrectDereferenceException.<init>(kotlin.String)kotlin.native.IncorrectDereferenceException + 84
        at 3   MyNativeFramework                   0x00000001048ad7bc ThrowIllegalObjectSharingException + 496
        at 4   MyNativeFramework                   x0000000104a6f1a0 _ZNK16KRefSharedHolder3refEv + 240
        at 5   MyNativeFramework                   0x0000000104a6eff4 -[KotlinBase release] + 48
        at 6   libobjc.A.dylib                     0x00000001aad36408 objc_release + 136
        at 7   PositionKit                         0x00000001044967e8 $s11PositionKit17MySensorC5startyyFySo14CMDeviceMotionCSg_s5Error_pSgtcfU_ + 684(lldb)

(已更改名称以保护封闭源代码)

我做错了什么?我是否必须以某种方式将浮点数组标记为共享?我已经阅读了 Kotlin/Native 中的数据冻结,但这似乎只适用于 kotlin 上下文中的对象。

【问题讨论】:

【参考方案1】:

这里有两个例外。 第二个将是 fixed 在即将发布的 Kotlin 1.3.60 版本中。

第一个可能是由于主线程访问在后台线程上创建的 Kotlin 对象使用object expression(可能是sensorDataType,它可能是MySensor 实例。冻结这个对象应该会有所帮助。

【讨论】:

感谢您的回答,我认为它指导了我正确的方向。 sensorDataType 是一个枚举,所以这是有道理的。我注意到我未能覆盖 Swift 端的两个属性,但是这样做并不能解决问题。如何冻结对象? This 告诉我我应该能够在任何对象上调用 freeze(),但尝试调用它会导致 Unresolved reference: freeze 即使在 kotlin.native.concurrent.* 上导入也是如此 sensorDataType 是一个枚举的事实让我觉得我在细节上错了。需要冻结的对象不是sensorDataType,而是MySensor 实例本身。 kotlin.native.concurrent.* 是 Native-only,所以它只在你的项目的 ios 源代码集中可用。

以上是关于Kotlin/Native - 非法尝试访问非共享 <object>的主要内容,如果未能解决你的问题,请参考以下文章

在 Cocoapod 中导入 Kotlin/Native 框架

Kotlin Multiplatform:共享多个目标(iOS、macOS)的实际类实现

C++ 非静态成员函数的非法调用

如何在 kotlin native 中使用 swift 库?

Kotlin native - 执行可执行文件

使用协程的 Kotlin/Native 多线程