Я работаю с API MusicPlayer и пытаюсь решить проблему с обратным вызовом пользователя.
У меня есть пользовательские события, которые помещаются в каждое событие нот MIDI. Когда ноты воспроизводятся, эти пользовательские события передают целочисленное значение ноты в функцию обратного вызова пользователя как * inEventData:
void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
{
UserEvent* event = (UserEvent *)inEventData;
UInt32 size = event->length;
UInt32 note = event->playedNote;
UInt32 timestamp = event->tStamp;
NSLog(@"Size: %lu Note: %lu, Timestamp: %lu", size, note, timestamp);
switch (note) {
case 60:
[whiteKey60 setImage:highlightA];
break;
default:
break;
}
}
На основании этих заметок я хотел бы внести изменения в пользовательский интерфейс. А именно, у меня есть несколько UIImageViews, которые я хотел бы иметь возможность обновлять различными изображениями в зависимости от значения примечания (см. Выше в выражении switch).
Функция обратного вызова пользователя связана с такой последовательностью:
MusicSequenceSetUserCallback(sequence, noteUserCallback, NULL);
Третий параметр вышеуказанной функции связан с параметром void * inClientData пользовательской функции обратного вызова.
Моя проблема в том, что когда я пытаюсь получить доступ к IBOutlets моего представления из функции обратного вызова пользователя, я не могу. Чтобы это исправить, я попытался передать контроллер представления в функцию MusicSequenceSetUserCallback следующим образом:
MusicSequenceSetUserCallback(sequence, noteUserCallback, self);
Проблема, с которой я столкнулся, заключается в том, что этот параметр inClientData имеет тип void , и я не могу передать объект ViewController *. Я попытался просто создать мост, когда я установил функцию обратного вызова, а затем снова подключился обратно в пользовательской функции обратного вызова, но, похоже, он не работал.
Если у кого-нибудь есть мысли о том, как мне это сделать. Даже если это совершенно другие методы, я был бы очень признателен.
Спасибо.
EDIT
Я попробовал следующее:
MusicSequenceSetUserCallback(sequence, noteUserCallback, (__bridge_retained void *)self);
и
void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
{
PracticeViewController* pvc = (__bridge_transfer PracticeViewController *)inClientData;
[pvc.whiteKey21 setImage:pvc.highlightA];
UserEvent* event = (UserEvent *)inEventData;
UInt32 size = event->length;
UInt32 note = event->playedNote;
UInt32 timestamp = event->tStamp;
NSLog(@"Size: %lu Note: %lu, Timestamp: %lu", size, note, timestamp);
switch (note) {
case 60:
break;
default:
break;
}
}
К сожалению, это дает мне эту ошибку: Поток 13 AURemoteIO :: IOThread: EXC_BAD_ACCESS (код = 2, адрес = 0x10)
EDIT
Изменение обоих мостов на __bridge заставляет ошибку замолчать, но она все еще не работает должным образом; Призыв к изменению изображения в whiteKey60 не работает. Это не проблема с соединением UIImageView, потому что выполнение того же в viewDidLoad работает нормально.
Что мне кажется в любом случае происходит, это то, что self не делает это с функцией или, возможно, разрывает соединение, когда оно проходит?