Swift 5.1:如何将 NULL 作为参数传递?

use*_*603 2 core-foundation ios swift swift5.1

我正在尝试为CFNotificationCenter.

文件指出:

姓名

要观察的通知的名称。如果为 NULL,则为对象发布的任何通知调用回调。如果 center 是 Darwin 通知中心,则此值不能为 NULL。

据我所知NULL,Swift 中不存在。那么这个论点应该是什么呢?

以下编译正常,但不是空字符串NULL

CFNotificationCenterAddObserver(
    CFNotificationCenterGetDistributedCenter(),
    UnsafeMutableRawPointer?.none,
    receiveNotification,
    "" as CFString,
    UnsafeRawPointer?.none,
    CFNotificationSuspensionBehavior.deliverImmediately
)
Run Code Online (Sandbox Code Playgroud)

我试过CFString?NSNull并且NSNull as String但是编译器会抱怨。

我误解了文档吗?如何为名称参数提供 NULL 值?

Mar*_*n R 5

简短回答:来自 (Objective-)C 的 Nullable 指针是Swift中的可选指针,您可以传递nil(又名Optional.none)作为名称,以便在对象发布的任何通知时调用。

一些背景:该函数的 C 声明是

CF_EXPORT void CFNotificationCenterAddObserver(CFNotificationCenterRef center,
               const void *observer,
               CFNotificationCallback callBack, 
               CFStringRef name,
               const void *object,
               CFNotificationSuspensionBehavior suspensionBehavior);
Run Code Online (Sandbox Code Playgroud)

其中name参数的类型是一个指针,声明为

typedef const struct CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef;
Run Code Online (Sandbox Code Playgroud)

它在(Objective-C)文档中明确说明name可以是NULL,但显然函数声明没有被审计为可空性,这就是为什么参数被声明为隐式解包可选

_ name: CFString!
Run Code Online (Sandbox Code Playgroud)

在斯威夫特。

请参阅Swift 博客中的Nullability 和 Objective-CSE-0055 使用 Optional 使不安全指针可空性显式,以获取有关可空性以及 (Objective-)C 指针如何导入 Swift 的更多信息。

所以name: CFString!只告诉我们 Swift 编译器不知道 Objective-C 的参数是否可以为 NULL ,否则它的行为就像一个常规的 optional CFString?,你可以传递一个nil值,它对应NULL于 (Objective-)C 中的空指针.

类似地,const void *object被导入 Swift 是_ object: UnsafeRawPointer!因为没有可空性注释,您可以nil在此处传递(您已经以显式形式执行的操作UnsafeRawPointer?.none)。