我正在研究利用MIDI設備的應用程序。與CoreMIDI操場一些打打鬧鬧之後,我發現如何讓MIDI輸入信號,所以我實現了這一點:從C風格指針訪問自我
func makeInputSource() {
var midiClient : MIDIClientRef = 0
var inPort : MIDIPortRef = 0
MIDIClientCreate("WobClient" as CFString, nil, nil, &midiClient)
MIDIInputPortCreate(midiClient, "WobClient_InPort" as CFString, {
(pktList: UnsafePointer<MIDIPacketList>, readProcRefCon: UnsafeMutableRawPointer?, srcConnRefCon: UnsafeMutableRawPointer?) in
let packetList : MIDIPacketList = pktList.pointee
var packet : MIDIPacket = packetList.packet
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
}
}
packet = MIDIPacketNext(&packet).pointee
}
}, nil, &inPort)
MIDIPortConnectSource(inPort, self.source, &self.source)
}
這就像一個魅力的作品使用的信號。現在,我想用信號編輯NSSlider
的價值,所以,自然而然,我想出了是這樣的:
self.slider_one?.integerValue = params[2]
然而,當我嘗試這樣做,我得到以下錯誤:
A C function pointer cannot be formed from a closure that captures context
所以,我想知道是,是否有從該封閉的內部訪問self
的方式,或者是有使用MIDI輸入快捷一些其他的方式?
謝謝。
---編輯: 至於問,修改後我的代碼:
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?) in
let packetList : MIDIPacketList = pktList.pointee
var packet : MIDIPacket = packetList.packet
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
}
}
let mySelf = Unmanaged<Wob>.fromOpaque(observer).takeUnretainedValue()
mySelf.slider_one?.integerValue = 25 // 25 is a test value
packet = MIDIPacketNext(&packet).pointee
}
}, &observer, &inPort)
MIDIPortConnectSource(inPort, self.source, &self.source)
}
這也可能是有益的:如何使用實例方法作爲回調函數,只需FUNC或立即關閉(http://stackoverflow.com/questions/33260808 /如何使用的實例-方法-AS-回調換功能,其通吃僅-FUNC - 或亮)。 –
@MartinR試圖這樣做:'UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())'然而,我仍然得到相同的錯誤 –
你不能在閉包內使用'self',你必須重構它從上下文指針中,請參閱鏈接到的答案中的let mySelf = Unmanaged ...。 –