Не удается преобразовать значение типа «UnsafePointer‹MIDINotification›» в ожидаемый тип аргумента «UnsafePointer‹_›»

Я пытаюсь обновить код из примера CoreMidi, который я нашел по адресу http://mattg411.com/swift-coremidi-callbacks/

И код датирован до Swift 3, поэтому мне нужно внести некоторые коррективы. Проблема в том, что мне практически никогда не приходилось играть с небезопасными указателями и друзьями. Итак, я думаю, что мне удалось решить несколько проблем, но одна из них остается, и я получаю эту ошибку Cannot convert value of type 'UnsafePointer<MIDINotification>' to expected argument type 'UnsafePointer<_>' код, который дает эту ошибку, ...UnsafePointer<MIDIObjectAddRemoveNotification>(message)

часть этого метода:

func MIDIUtil_MIDINotifyProc(message: UnsafePointer<MIDINotification>, refCon: UnsafeMutableRawPointer) -> Void
    {
        let notification:MIDINotification = message.pointee

        if (notification.messageID == .msgObjectAdded || notification.messageID == .msgObjectRemoved)
        {
            let msgPtr:UnsafePointer<MIDIObjectAddRemoveNotification> = UnsafePointer<MIDIObjectAddRemoveNotification>(message)
            let changeMsg:MIDIObjectAddRemoveNotification = msgPtr.pointee
            let h:AnyObject = unbridgeMutable(ptr: refCon)
            let handler:MIDICallbackHandler = h as! MIDICallbackHandler
            handler.processMidiObjectChange(message: changeMsg)
        }
    }

РЕДАКТИРОВАТЬ: я создал небольшой проект из нескольких руководств, которые нашел в сети. включая исправление от пользователя 28434

https://github.com/nissaba/Librarian


person Pascale Beaulac    schedule 02.04.2018    source источник


Ответы (1)


Если я правильно понял код, строка

let msgPtr:UnsafePointer<MIDIObjectAddRemoveNotification> = UnsafePointer<MIDIObjectAddRemoveNotification>(message)

следует перепривязать память с MIDINotification на MIDIObjectAddRemoveNotification.

В Swift 3.0+ вы должны сделать это, используя withMemoryRebound(to:capacity:_:).

Что-то вроде этого:

let msgPtr:UnsafePointer<MIDIObjectAddRemoveNotification> = message.withMemoryRebound(to: MIDIObjectAddRemoveNotification.self, capacity: 1) { (pointer) in
    return pointer
}

Или есть другой способ: приведя UnsafePointer к UnsafeRawPointer, а затем "предположим, что память ограничена"< /а>:

let msgPtr:UnsafePointer<MIDIObjectAddRemoveNotification> = UnsafeRawPointer(message).assumingMemoryBound(to: MIDIObjectAddRemoveNotification.self)
person user28434'mstep    schedule 02.04.2018
comment
отлично, ошибка исчезла, спасибо. К сожалению, я получаю сбой во время выполнения (поток 1: EXC_BAD_INSTRUCTION (код = EXC_I386_INVOP, субкод = 0x0)) из другой части кода, и я не знаю, работает ли это так, как нужно. Даю вам ответ на это, поскольку ошибка исчезла. Мне грустно, что CoreMidi API не имеет быстрого интерфейса. нужно сделать все voodoo mombo jumbo, чтобы заставить это работать. Надеясь, что однажды он будет переработан, как API AddressBook. - person Pascale Beaulac; 02.04.2018
comment
Что ж, это вуду типа указателя является наследием интерфейса C. C не хватает наследования, используя это в качестве замены. - person user28434'mstep; 02.04.2018
comment
Да. и грустно, что Apple не тратит время на то, чтобы обернуть его в удобный для пользователя быстрый API. Но это другая тема. - person Pascale Beaulac; 02.04.2018