You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为iOS编写Kotlin Native协程后台Dispatcher遇非法引用异常求助

Fixing kotlin.native.IncorrectDereferenceException for GCD Global Queue Coroutine Dispatcher in Kotlin/Native iOS

The exception you're hitting comes directly from Kotlin/Native's memory safety model, which blocks non-shared (non-frozen) objects from being accessed across different threads. Your current dispatcher passes a Runnable created on one thread to a GCD global queue thread, but that Runnable (and any objects it captures) aren't marked safe for cross-thread use.

Here's how to fix this:

Step 1: Freeze the Runnable for Cross-Thread Access

Update your NsQueueDispatcher to freeze the Runnable before passing it to dispatch_async. Freezing makes the object (and all its referenced objects) immutable, which lets the runtime know it's safe to access across threads:

val runCoroutineDispatcher: CoroutineContext = NsQueueDispatcher

object NsQueueDispatcher : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        // Freeze the block to enable safe cross-thread execution
        val frozenBlock = block.freeze()
        dispatch_async(
            dispatch_get_global_queue(
                NSNumber(double = DISPATCH_QUEUE_PRIORITY_DEFAULT.toDouble()).integerValue, 
                0
            )
        ) { frozenBlock.run() }
    }
}

Why This Resolves the Exception

Kotlin/Native uses thread confinement by default: objects can only be used on the thread they were created on unless they're frozen. By freezing the Runnable, you're explicitly marking it as immutable and safe for use on any thread, which eliminates the IncorrectDereferenceException.

Additional Tips

  • If your coroutine block captures mutable state, use thread-safe constructs like AtomicReference from kotlin.native.concurrent instead of regular variables.
  • For most background work, you can also use the built-in Dispatchers.Default from kotlinx.coroutines—it's already optimized for Kotlin/Native background tasks. But if you need a custom GCD-based dispatcher, the fix above will work perfectly.

Testing your sample code with the modified dispatcher should now run without errors:

CoroutineScope(runCoroutineDispatcher).launch { println("Hello World") }

内容的提问来源于stack exchange,提问作者Sebastian Ohm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:00:26