user3574603
user3574603

Reputation: 3628

Swift 5.1: How can I pass NULL as an argument?

I am trying to set an obeserver for CFNotificationCenter.

The documentation states:

name

The name of the notification to observe. If NULL, callback is called for any notification posted by object. If center is a Darwin notification center, this value must not be NULL.

From what I understand NULL doesn't exist in Swift. So what should this argument be?

The following compiles fine, but a blank string isn't NULL:

CFNotificationCenterAddObserver(
    CFNotificationCenterGetDistributedCenter(),
    UnsafeMutableRawPointer?.none,
    receiveNotification,
    "" as CFString,
    UnsafeRawPointer?.none,
    CFNotificationSuspensionBehavior.deliverImmediately
)

I've tried CFString?, NSNull and NSNull as String but the compiler complains.

Have I misunderstood the documentation? How do I supply a NULL value for the name paramenter?

Upvotes: 3

Views: 2774

Answers (1)

Martin R
Martin R

Reputation: 540065

Short answer: Nullable pointers from (Objective-)C are optional pointers in Swift, and you can pass nil (aka Optional.none) for the name in order to be called for any notification posted by the object.

Some background: The C declaration of that function is

CF_EXPORT void CFNotificationCenterAddObserver(CFNotificationCenterRef center,
               const void *observer,
               CFNotificationCallback callBack, 
               CFStringRef name,
               const void *object,
               CFNotificationSuspensionBehavior suspensionBehavior);

where the type of the name parameter is a pointer, declared as

typedef const struct CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef;

It is explicitly stated in the (Objective-C) documentation that name can be NULL, but apparently the function declaration has not been audited for nullability, and that is why the parameter is declared as an implicit unwrapped optional

_ name: CFString!

in Swift.

See Nullability and Objective-C in the Swift blog and SE-0055 Make unsafe pointer nullability explicit using Optional for more information about nullability and how (Objective-)C pointers are imported to Swift.

So name: CFString! only tells us that the Swift compiler does not know if the Objective-C parameter can be NULL or not, otherwise it behaves like a regular optional CFString?, and you can pass a nil value, which corresponds to a null pointer NULL in (Objective-)C.

Similarly, const void *object is imported to Swift as _ object: UnsafeRawPointer! because there is no nullability annotation, and you can pass nil here (what you already do in the explicit form UnsafeRawPointer?.none).

Upvotes: 5

Related Questions