问题
I use this code to send midi sysEx. It s perfect for sending "fix" data but now i need to send data with different size.
var midiPacket:MIDIPacket = MIDIPacket()
midiPacket.length = 6
midiPacket.data.0 = data[0]
midiPacket.data.1 = data[1]
midiPacket.data.2 = data[2]
midiPacket.data.3 = data[3]
midiPacket.data.4 = data[4]
midiPacket.data.5 = data[5]
//...
//MIDISend...
Now imagine i have a String name "TROLL" but the name can change. I need something like this :
var name:String = "TOTO"
var nameSplit = name.components(separatedBy: "")
var size:Int = name.count
midiPacket.length = UInt16(size)
for i in 0...size{
midiPacket.data.i = nameSplit[i]
}
//...
//MIDISend...
But this code don t work because i can t use "i" like this with a tuple. If someone knows how to do that.
Thanks in advance. KasaiJo
回答1:
C arrays are imported to Swift as tuples. But the Swift compiler
preserves the memory layout of imported C structures (source), therefore you can rebind a pointer to the tuple
to an pointer to UInt8
:
withUnsafeMutablePointer(to: &midiPacket.data) {
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: midiPacket.data)) {
dataPtr in // `dataPtr` is an `UnsafeMutablePointer<UInt8>`
for i in 0..<size {
dataPtr[i] = ...
}
}
}
回答2:
I don't know any proper way to do that, as tuples are compound type and can't be extended to add additional functionality.
One way of improving it I can think about is extracting it to a func like:
func setMidiPacket(_ midi: MIDIPacket fromArray array: [ProbablyInt]) {
midiPacket.length = 6
midiPacket.data.0 = data[0]
midiPacket.data.1 = data[1]
midiPacket.data.2 = data[2]
midiPacket.data.3 = data[3]
midiPacket.data.4 = data[4]
midiPacket.data.5 = data[5]
}
setMidiPacket(midi, data)
来源:https://stackoverflow.com/questions/46972156/use-statement-for-to-write-in-a-tuple