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

启用Xcode C++与Objective-C互操作性时AVFoundation通知常量缺失问题

问题场景

在Xcode中启用直接C++与Objective-C互操作性时,运行以下代码:

NotificationCenter.default.addObserver(self,
                                       selector: #selector(subjectAreaDidChange(_:)),
                                       name: .AVCaptureDeviceSubjectAreaDidChange,
                                       object: nil)

会触发编译错误:

Type 'NSNotification.Name?' has no member 'AVCaptureDeviceSubjectAreaDidChange'

但切换为仅C/Objective-C互操作性模式时,代码可正常编译,且该问题主要影响AVFoundation框架中通过Objective-C扩展定义的NSNotification.Name常量。

报错原因

直接C与Objective-C互操作性模式(Objective-C Direct Mode)下,Swift对Objective-C框架的导入规则发生了变化:AVFoundation中AVCaptureDeviceSubjectAreaDidChange这类通知名,是通过Objective-C的分类扩展或宏定义绑定到NSNotification.Name上的,而直接模式下Swift无法正确识别这类跨语言扩展的成员,导致编译器找不到对应的属性。

解决方法
  • 直接使用通知字符串构造实例:跳过点语法,直接用通知的原始字符串创建NSNotification.Name实例,代码如下:
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(subjectAreaDidChange(_:)),
                                           name: NSNotification.Name("AVCaptureDeviceSubjectAreaDidChange"),
                                           object: nil)
    
  • 手动扩展NSNotification.Name:在Swift代码中自行定义对应的静态成员,之后仍可使用点语法调用:
    extension NSNotification.Name {
        static let AVCaptureDeviceSubjectAreaDidChange = NSNotification.Name("AVCaptureDeviceSubjectAreaDidChange")
    }
    
  • 拆分代码到纯Objective-C文件:将依赖此类通知的逻辑移至纯Objective-C(.m)文件中,在Swift中通过桥接调用这部分代码,避开直接互操作性模式的限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:09:55