Правильный синтаксис для отмены регистрации обратного вызова в каркасе DiskArbitration

Я собираюсь внедрить наблюдателя, который будет уведомлен, когда исчезнет определенный объем.

Уведомления в NSWorkspace не вариант, потому что мне нужно уведомление об отключенном устройстве, а не отключенном устройстве.

Регистрация довольно проста (я пропустил обработку ошибок)

var callbackSession : DASession?

let callbackSession = DASessionCreate(kCFAllocatorDefault)
DASessionSetDispatchQueue(callbackSession!, DispatchQueue.global())  
DARegisterDiskDisappearedCallback(callbackSession!, nil, volumeDidDisappearCallback, nil)

Закрытие обратного вызова

let volumeDidDisappearCallback : DADiskDisappearedCallback = { (disk, context) in
   // do something with disk
}

Незарегистрированный метод

func DAUnregisterCallback(_ session: DASession, _ callback: UnsafeMutableRawPointer, _ context: UnsafeMutableRawPointer?)

ожидает общий UnsafeMutableRawPointer а не один из конкретных типов обратного вызова.

Когда я передаю закрытие обратного вызова в callback параметр, который я получаю

Невозможно преобразовать значение типа 'DADiskDisappearedCallback' (также известный как @convention(c) (DADisk, Optional) -> ()') в ожидаемый тип аргумента'UnsafeMutableRawPointer'

Мой вопрос: как я могу преобразовать объект обратного вызова volumeDidDisappearCallback в UnsafeMutableRawPointer?

1 ответ

Решение

DADiskDisappearedCallback определяется как

public typealias DADiskDisappearedCallback = @convention(c) (DADisk, UnsafeMutableRawPointer?) -> Swift.Void

который является отображением Swift указателя на функцию C

typedef void (*DADiskAppearedCallback)(DADiskRef disk, void *context);

Функция отмены регистрации определяется в C как

void DAUnregisterCallback(DASessionRef session, void *callback, void *context);

с void *callback параметр, и в C вы можете передавать различные виды указателей функции обратного вызова (DADiskAppearedCallback, DADiskDescriptionChangedCallback...) без кастинга.

В Swift вы должны явно привести указатель функции к пустому указателю:

let cb = unsafeBitCast(volumeDidDisappearCallback, to: UnsafeMutableRawPointer.self)
DAUnregisterCallback(callbackSession!, cb, nil)
Другие вопросы по тегам