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

Swift Actor报错:向实例发送未识别选择器问题求助

问题分析与解决方案

错误原因解析

你遇到的-[NSTaggedPointerString objectForKey:]: unrecognized selector sent to instance 0x8000000000000000错误,本质是把NSTaggedPointerString(苹果优化的轻量字符串类型)当成NSDictionary调用了objectForKey:方法,而该字符串类型并没有实现这个方法。结合你的代码场景,问题根源在于:

  • 同一个Draft的保存任务被多次并发触发,多线程环境下draft.localUUID的内存访问出现异常,导致类型识别混乱;
  • DraftQueue仅实现了任务清理逻辑,未跟踪当前正在执行的保存任务,多个任务同时操作同一份draft,引发Swift与ObjC桥接时的类型混淆;
  • Draft的localUUID属性未做线程安全保障,多线程访问时返回了异常的字符串实例。

代码修复方案

1. 完善DraftQueue的任务管理逻辑

修改DraftQueue,添加任务提交方法,确保同一时刻只有一个任务处理同一个draft,同时自动管理任务的生命周期:

actor DraftQueue {
    private var taskQueue = [String: Task<Void, Never>]()

    func submitSaveTask(for uuid: String, task: @escaping () async -> Void) {
        // 取消并移除旧任务
        taskQueue[uuid]?.cancel()
        taskQueue[uuid] = nil
        
        // 创建新任务并加入队列,任务完成后自动移除
        let newTask = Task {
            await task()
            taskQueue[uuid] = nil
        }
        taskQueue[uuid] = newTask
    }

    func cleanQueueElement(uuid: String) {
        taskQueue[uuid]?.cancel()
        taskQueue[uuid] = nil
    }
}

2. 修改saveDraft方法,使用新的任务提交逻辑

private func saveDraft(draft: Draft, mailboxManager: MailboxManager) async {
    await draftQueue.submitSaveTask(for: draft.localUUID) {
        await mailboxManager.save(draft: draft)
    }
}

3. 保障Draft属性的线程安全

确保localUUID在多线程环境下返回稳定的字符串实例,比如用@MainActor修饰:

class Draft {
    @MainActor let localUUID: String
    // 其他属性定义...
}

4. 优化syncDraft的并发控制

避免一次性创建过多并发任务,用TaskGroup限制并发数:

public func syncDraft(mailboxManager: MailboxManager) {
    Task {
        let drafts = await mailboxManager.draftWithPendingAction()
        await withTaskGroup(of: Void.self) { group in
            let maxConcurrentTasks = 5 // 根据实际情况调整并发数
            var activeTaskCount = 0
            
            for draft in drafts {
                if activeTaskCount >= maxConcurrentTasks {
                    await group.next()
                    activeTaskCount -= 1
                }
                group.addTask {
                    await self.saveDraft(draft: draft, mailboxManager: mailboxManager)
                }
                activeTaskCount += 1
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:40:33