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

如何擦除NotificationCenter.Notifications类型?解决Sendable兼容报错

解决Notification异步序列merge时的Sendable合规问题

问题根源在于:尽管你通过map将Notification转换为Void,但NotificationCenter.Notifications这个底层异步序列本身并未遵循Sendable协议,而merge()要求输入的异步序列必须满足Sendable约束,因此报错依然存在。

以下是两种可行的解决方法:

方法一:使用AsyncChannel中转(推荐)

通过AsyncChannel将非Sendable的通知序列转换为Sendable的事件流,完全符合Swift并发安全规范:

import AsyncAlgorithms
import Foundation

extension Notification.Name {
    static let noteOne = Notification.Name("noteOne")
    static let noteTwo = Notification.Name("noteTwo")
}

// 创建用于中转事件的异步通道
let channel1 = AsyncChannel<Void>()
let channel2 = AsyncChannel<Void>()

// 启动任务监听通知,收到时向通道发送空值
Task {
    for await _ in NotificationCenter.default.notifications(named: .noteOne) {
        await channel1.send()
    }
}

Task {
    for await _ in NotificationCenter.default.notifications(named: .noteTwo) {
        await channel2.send()
    }
}

// 合并两个通道的事件流
let merged = merge(channel1, channel2)

// 监听合并后的事件
Task {
    for await _ in merged {
        print("触发目标事件")
    }
}

方法二:显式标记序列为@unchecked Sendable

若你仅关心通知触发、不处理任何Notification内容,可安全地将转换后的序列标记为@unchecked Sendable,快速满足merge()的约束:

import AsyncAlgorithms
import Foundation

extension Notification.Name {
    static let noteOne = Notification.Name("noteOne")
    static let noteTwo = Notification.Name("noteTwo")
}

// 转换序列并标记为@unchecked Sendable
let note1 = NotificationCenter.default.notifications(named: .noteOne)
    .map { _ in () }
    .eraseToAnyAsyncSequence() as any AsyncSequence & @unchecked Sendable

let note2 = NotificationCenter.default.notifications(named: .noteTwo)
    .map { _ in () }
    .eraseToAnyAsyncSequence() as any AsyncSequence & @unchecked Sendable

// 合并序列
let merged = merge(note1, note2)

// 监听事件
Task {
    for await _ in merged {
        print("触发目标事件")
    }
}

注意:使用@unchecked Sendable时,需确保你确实没有保留或传递任何非Sendable的Notification相关数据,避免并发安全隐患。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:02:39