在 Xcode 中启用直接 C++ 互操作性时,下面是这个简单的代码
NotificationCenter.default.addObserver(self,
selector: #selector(subjectAreaDidChange(_:)),
name: .AVCaptureDeviceSubjectAreaDidChange,
object: nil)
给我以下错误
Type 'NSNotification.Name?' has no member 'AVCaptureDeviceSubjectAreaDidChange'
但是如果我将
C++ and Objective-C interoperability
切换为 C / Objective-C
那么代码编译时不会出现错误。
该问题似乎仅影响
NSNotification.Name
框架中的 AVFoundation
常量(尽管可能还有更多)。
为什么会出现此错误以及如何修复它?
简短回答
这是 Xcode 15 的一个已知错误 (https://forums.developer.apple.com/forums/thread/733693)。
您可以通过使用所需通知的原始字符串来解决这个问题:
NotificationCenter.default.addObserver(self,
selector: #selector(subjectAreaDidChange),
name: .init(rawValue: "AVCaptureDeviceSubjectAreaDidChangeNotification"),
object: nil)
长答案
如果你往里面看
AVFoundation/AVCaptureDevice.h
你会发现:
AVF_EXPORT NSString *const AVCaptureDeviceSubjectAreaDidChangeNotification API_AVAILABLE(ios(5.0), macCatalyst(14.0), tvos(17.0)) API_UNAVAILABLE(macos, visionos) API_UNAVAILABLE(watchos);
互操作性只是在导出的字符串中查找“Notification”后缀并将其转换为
NSNotification.Name
,例如:
AVCaptureDeviceSubjectAreaDidChangeNotification -> NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange
应用程序中的字符串也同样适用:
// Test.h
extern NSString *const MyNotification;
// Test.m
NSString *const MyNotification = @"MyNotification";
然后你可以在你的swift文件中写入:
let notification: NSNotification.Name = .My
但它仅适用于
C / Objective-C
,不适用于 C++ / Objective-C++
,因为编译器不会在 NSNotification.Name
扩展中生成适当的属性,例如:
extension NSNotification.Name {
...
@available(iOS 5.0, *)
public static let AVCaptureDeviceSubjectAreaDidChange: NSNotification.Name
}