You need to enable JavaScript to run this app. Swift中如何在for循环里为MIDIPacket的UInt8元组批量赋值
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在for循环里为MIDIPacket的UInt8元组批量赋值

解决方案

对于C语言导入的固定长度元组,Swift原生不支持下标访问,最稳定高效的实现方式是直接操作元组的连续内存空间进行赋值:

方案1:直接内存拷贝(推荐)

import CoreMIDI

var packet = MIDIPacket()
let converted: [UInt8] = [0x01, 0x02, 0x5e, 0x3f]
let startIndex = 0 // 赋值起始位置

// 越界保护:CoreMIDI中MIDIPacket的data元组默认长度为256,需确保写入范围不超限
let maxDataLength = MemoryLayout.size(ofValue: packet.data)
precondition(startIndex + converted.count <= maxDataLength, "写入内容超出data最大容量")

// 内存操作赋值
withUnsafeMutableBytes(of: &packet.data) { buffer in
    let uint8Ptr = buffer.baseAddress!.assumingMemoryBound(to: UInt8.self)
    // 批量内存拷贝,比循环赋值性能更高
    uint8Ptr.advanced(by: startIndex).initialize(from: converted, count: converted.count)
}

// 注意:必须手动设置packet的length属性为实际写入的有效数据长度,否则MIDI服务无法正常解析
packet.length = UInt16(startIndex + converted.count)

方案2:扩展MIDIPacket支持下标访问

如果需要频繁修改data的指定位置,可以给MIDIPacket添加下标扩展,后续使用更方便:

extension MIDIPacket {
    subscript(dataIndex: Int) -> UInt8 {
        get {
            precondition(0..<MemoryLayout.size(ofValue: data) ~= dataIndex, "data下标越界")
            return withUnsafeBytes(of: data) {
                $0.baseAddress!.assumingMemoryBound(to: UInt8.self).advanced(by: dataIndex).pointee
            }
        }
        set {
            precondition(0..<MemoryLayout.size(ofValue: data) ~= dataIndex, "data下标越界")
            withUnsafeMutableBytes(of: &data) {
                $0.baseAddress!.assumingMemoryBound(to: UInt8.self).advanced(by: dataIndex).pointee = newValue
            }
        }
    }
}

扩展后可以直接按照你期望的逻辑赋值:

let converted = [0x01, 0x02, 0x5e]
var k = 0 // 赋值起始索引
for i in 0..<converted.count {
    packet[k] = converted[i]
    k += 1
}
packet.length = UInt16(k)

注意事项

  • 不要使用Mirror反射进行赋值操作:反射拿到的是值类型的只读副本,修改不会生效,且性能远低于直接内存操作
  • 必须正确设置packet.length属性,值为所有写入data的有效数据总长度,否则CoreMIDI会识别为无效数据包

内容的提问来源于stack exchange,提问作者Cheetaiean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 08:15:04