我在autoreleasepool中解析midi消息。在确定正在发送的消息之后,我使用dispatch_async(dispatch_get_main_queue()调用主线程。这似乎在大多数情况下运行良好但偶尔会在线路停止时发生崩溃
while (semaphore_wait(midiReceivedSemaphore) == KERN_SUCCESS ) {
该方法如下所示:
@autoreleasepool {
unsigned int maxPacketLength = 0x100;
unsigned char* data = malloc(maxPacketLength);
UInt16 length;
while (semaphore_wait(midiReceivedSemaphore) == KERN_SUCCESS ) {
midi_packet_buffer_next_packet_length(midiPacketBuffer, &length);
if( length > 0) {
length = midi_packet_buffer_read(midiPacketBuffer, data, length);
for (unsigned int packetContentsIndex = 0; packetContentsIndex < length; packetContentsIndex++) {
while (packetContentsIndex < length) {
Byte command = data[packetContentsIndex];
switch (command) {
case 0xA0: //aftertouch
commandLength += 2;
int meterChannel = data[packetContentsIndex +1];
int meterValue = data[packetContentsIndex +2];
if (meterValue < 0x10)
{
dispatch_async(dispatch_get_main_queue(), ^{
[delegate sendLevelMeterPT:meterChannel withValue:meterValue ];
});
}
break;
default:
break;
}
}
}
}
}
free(data);
}
这是处理MIDI信息的一种非常糟糕的方式吗?我使用dispatch_async的原因是它不会减慢midi处理线程的速度,在使用dispatch_async之前,如果它们快速进入,该方法会丢失一些消息。现在它捕获了所有消息但我偶尔会崩溃。我想我可能不得不重写整个midi处理方法,但想知道正确的方法去做。任何建议都会很棒。