启用 C++ 互操作性时缺少一些 NSNotification.Name 常量

问题描述 投票:0回答:1

在 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
常量(尽管可能还有更多)。

为什么会出现此错误以及如何修复它?

swift xcode avfoundation nsnotificationcenter nsnotifications
1个回答
0
投票

简短回答

这是 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
}
© www.soinside.com 2019 - 2024. All rights reserved.