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

Swift 5.5:主线程处理通知时如何正确访问通知对象?

解决Notification在@Sendable闭包中的捕获警告问题

问题代码

class ViewController : NSViewController {
    override func loadView() {
        NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: view, queue: .main) { [self] n in
            DispatchQueue.main.async {
                self.resizeSubviews(animate: false, sender: n.object) // <- 此处触发警告
            }
        }
    }

    func resizeSubviews(animate: Bool, sender: Any?) {
    }
}

触发的警告

Capture of 'n' with non-sendable type 'Notification' in a `@Sendable` closure

问题原因

通知处理闭包本身是@Sendable类型,内层的DispatchQueue.main.async闭包也会被推断为@Sendable。由于Notification当前未遵循Sendable协议,将其捕获进内层@Sendable闭包时,编译器会抛出线程安全相关警告。

解决方案

方案1:提前提取所需属性(推荐)

在进入内层闭包前,先提取需要的n.object,让内层闭包仅捕获该属性而非整个Notification实例,从根源避免捕获非Sendable类型:

class ViewController : NSViewController {
    override func loadView() {
        NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: view, queue: .main) { [self] n in
            // 提前提取属性,避免捕获整个Notification
            let targetSender = n.object
            DispatchQueue.main.async {
                self.resizeSubviews(animate: false, sender: targetSender)
            }
        }
    }

    func resizeSubviews(animate: Bool, sender: Any?) {
    }
}

方案2:标记内层闭包为@unchecked Sendable(谨慎使用)

如果确实需要访问整个Notification实例,且能确认当前场景无线程安全风险(比如所有操作都在主线程),可以给内层闭包添加@unchecked Sendable标记,绕过编译器警告:

class ViewController : NSViewController {
    override func loadView() {
        NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: view, queue: .main) { [self] n in
            DispatchQueue.main.async { @unchecked Sendable in
                self.resizeSubviews(animate: false, sender: n.object)
            }
        }
    }

    func resizeSubviews(animate: Bool, sender: Any?) {
    }
}

注意:@unchecked Sendable会关闭编译器的Sendable检查,必须确保代码逻辑不会引发线程安全问题才能使用。


内容的提问来源于stack exchange,提问作者C. Ocoa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:27:15