将自我投射到UnsafeMutablePointer 产生EXC_BAD_INSTRUCTION
问题描述:
我正在使用Swift应用程序,在该应用程序中,我利用特定的MIDI信号并使用它。一个例子是:我想根据输入信号移动NSSlider的值。所以,我所做的是创建一个MIDI输入流(可行),我现在需要做的是取值并将其设置为self.wave_mode_slider?.integerValue
。将自我投射到UnsafeMutablePointer <Void>产生EXC_BAD_INSTRUCTION
我从那里我使输入连接如下方法:
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
变量更改为UnsafeMutableRawPointer
答
在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!")
}
}
}
它应该是'MIDIPortConnectSource(运行轨迹,self.source,观察者)',而'&' - 我建议在http://*.com/questions/43589188/access-self-from-交流风格指针#comment74230252_43589188 :) –
@MartinR哈哈错过了!我将更新代码,因为问题仍然存在, –
当然,如果您传递“observer”的内容或该变量的地址,它会有所不同。 –