将self转换为UnsafeMutablePointer <void>会导致EXC_BAD_INSTRUCTION

时间:2017-04-25 07:48:00

标签: swift macos cocoa midi coremidi

我正在使用Swift应用程序,在那里我利用来自特定的MIDI信号并使用它。一个例子是:我想根据输入信号移动NSSlider的值。所以,我所做的是创建一个MIDI输入流(可以工作),我现在需要做的是取值并将其设置为jdbc:oracle:thin:@server:1521:db

我进行输入连接的方法如下:

self.wave_mode_slider?.integerValue

正如你所看到的,我有一个像这样的观察者变量:

func makeInputSource() { var midiClient : MIDIClientRef = 0 var inPort : MIDIPortRef = 0 var observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque()) MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient) MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, { (pktList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) -> Void in let packetList : MIDIPacketList = pktList.pointee var packet : MIDIPacket = packetList.packet let mySelf = Unmanaged<Wob>.fromOpaque(readProcRefCon!).takeUnretainedValue() for _ in 1...packetList.numPackets { let bytes = Mirror(reflecting: packet.data).children var params : [UInt64] = [] var i = packet.length for (_, attr) in bytes.enumerated() { let string = String(format: "%02X ", attr.value as! UInt8) params.append(UInt64(strtoul(string, nil, 16))) i -= 1 if (i <= 0) { break } } mySelf.wave_mode_slider?.integerValue = ("\(params[2])" as NSString).integerValue packet = MIDIPacketNext(&packet).pointee } }, nil, &inPort) MIDIPortConnectSource(inPort, self.source, &observer) }

然后我将其传递给闭包,我尝试使用这样:

var observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())

但是,这会在声明let mySelf = Unmanaged<Wob>.fromOpaque(readProcRefCon!).takeUnretainedValue() mySelf.wave_mode_slider?.integerValue = ("\(params[2])" as NSString).integerValue 的行上导致EXC_BAD_INSTRUCTION

我还尝试使用mySelf变体,但这导致了相同的retained

现在,我不是一个经验丰富的快速开发者,特别是当涉及到这些东西时,所以可能是我错过了一些明显的东西,所以有人知道为什么会这样吗?

由于

编辑----根据建议,我稍微更改了代码,

EXC_BAD_INSTRUCTION

成了

MIDIPortConnectSource(inPort, self.source, &observer)

这也让我将MIDIPortConnectSource(inPort, self.source, observer) 变量更改为observer

1 个答案:

答案 0 :(得分:1)

在Swift 4上(接收cc):

@objc func receiveMIDI(_ sender: UIButton) {

    let observer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
    MIDIClientCreate(s, nil, nil, &midiClient);
    MIDIInputPortCreate(midiClient, p, {
    (pktList: UnsafePointer<MIDIPacketList>,
        readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in
            // callback block
            let packetList:MIDIPacketList = pktList.pointee
            var packet:MIDIPacket = packetList.packet

            for _ in 1...packetList.numPackets{
                let bytes = Mirror(reflecting: packet.data).children
                var dumpStr = ""


                var i = packet.length
                for (_, attr) in bytes.enumerated(){
                        dumpStr += String(format:"%02d ", attr.value as! UInt8)
                        i -= 1
                        if (i <= 0)
                        {
                            break
                        }
                }
                let midi = dumpStr.split(separator: " ", maxSplits: 2, omittingEmptySubsequences: true)
                var midiIntValues = [Int(midi[0]),Int(midi[1]),Int(midi[2].trimmingCharacters(in: .whitespaces))]
                if let src = srcConnRefCon{
                    let mySelf = Unmanaged<DetailViewController>.fromOpaque(src).takeUnretainedValue()
                    if let v = midiIntValues[2]{
                       // print("control \(midiIntValues[1]) has \(v) value")
                    }

                }
                packet = MIDIPacketNext(&packet).pointee
            }
            // end callback block
        }, nil, &inputPort);

    let sourceCount = MIDIGetNumberOfSources()
    print("source count \(sourceCount)")

    for srcIndex in 0 ..< sourceCount {
        var source = MIDIGetSource(srcIndex)
        let status = MIDIPortConnectSource(inputPort,source,observer)
        if status == noErr {
            print("Connected to inputPort")
        } else {
            print("There was an error connecting the ports!")
        }
    }
}