现状
项目仍是 SWIFT_VERSION = 5.0。当前 Swift 5 构建下 Swift 6 warning 已归零,
且以下四处已提前修好(零行为变化,已在 main 上):
ShellResolver.cache — 访问本就由 NSLock 串行化,补 nonisolated(unsafe) 声明事实;
SelectedTextReader — kAXTrustedCheckOptionPrompt 在 SDK 里是可变全局,改用 @preconcurrency import;
CodexProvider.CodexResponses.cancelled — 字段是 [String: Any] 故类型无法 Sendable,值本身不可变;
CodexProvider.LineReader — readabilityHandler 任意线程回调,内部由 NSCondition 保护,标注 @unchecked Sendable。
剩余阻塞
实测 xcodebuild ... SWIFT_VERSION=6 还剩 6 个错误,全部是同一类
(@MainActor 类型的 deinit 是 nonisolated,访问非 Sendable 属性):
| 文件 |
属性 |
FloatingPanel.swift:127 |
globalClickMonitor |
MiniHUDPanel.swift:153 |
globalClickMonitor |
LiveSubtitlesOverlayPanel.swift:54 |
screenObserver |
HotKeyManager.swift:229/232 |
hotKeyRefs / eventHandlerRef |
CleanTextScrollView.swift:278 |
scrollWorkItem |
为什么单独做
切换语言模式会改变默认 actor 推断的严格程度。真正需要严格检查的是音频链路
(SystemAudioCaptureService 的 @unchecked Sendable + nonisolated(unsafe) delegate,
Core Audio IO 线程无同步读 delegate 并回调 ASR)——而 @unchecked 恰恰不会
被 Swift 6 检查出来。所以这次切换的收益是「未来不再退化」,不是「立刻修掉现有竞态」。
方向
deinit 用 isolated deinit(SE-0371,Xcode 26 的 Swift 版本已支持),
或把清理逻辑移出 deinit。改完再单独评估音频链路是否值得从
@unchecked Sendable 换成真正的 actor 隔离。
需要 Runtime 证据:切换后实时字幕的启动/停止/语言切换全链路要真机跑一遍。
现状
项目仍是
SWIFT_VERSION = 5.0。当前 Swift 5 构建下 Swift 6 warning 已归零,且以下四处已提前修好(零行为变化,已在 main 上):
ShellResolver.cache— 访问本就由NSLock串行化,补nonisolated(unsafe)声明事实;SelectedTextReader—kAXTrustedCheckOptionPrompt在 SDK 里是可变全局,改用@preconcurrency import;CodexProvider.CodexResponses.cancelled— 字段是[String: Any]故类型无法 Sendable,值本身不可变;CodexProvider.LineReader—readabilityHandler任意线程回调,内部由NSCondition保护,标注@unchecked Sendable。剩余阻塞
实测
xcodebuild ... SWIFT_VERSION=6还剩 6 个错误,全部是同一类(
@MainActor类型的deinit是 nonisolated,访问非 Sendable 属性):FloatingPanel.swift:127globalClickMonitorMiniHUDPanel.swift:153globalClickMonitorLiveSubtitlesOverlayPanel.swift:54screenObserverHotKeyManager.swift:229/232hotKeyRefs/eventHandlerRefCleanTextScrollView.swift:278scrollWorkItem为什么单独做
切换语言模式会改变默认 actor 推断的严格程度。真正需要严格检查的是音频链路
(
SystemAudioCaptureService的@unchecked Sendable+nonisolated(unsafe) delegate,Core Audio IO 线程无同步读 delegate 并回调 ASR)——而
@unchecked恰恰不会被 Swift 6 检查出来。所以这次切换的收益是「未来不再退化」,不是「立刻修掉现有竞态」。
方向
deinit用isolated deinit(SE-0371,Xcode 26 的 Swift 版本已支持),或把清理逻辑移出
deinit。改完再单独评估音频链路是否值得从@unchecked Sendable换成真正的 actor 隔离。需要 Runtime 证据:切换后实时字幕的启动/停止/语言切换全链路要真机跑一遍。