我正在使用MusicPlayer API,我正在尝试使用用户回调解决我遇到的问题。
我有用户事件放在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;
}
}
根据这些说明,我想对UI进行更改。也就是说,我有许多UIImageViews,我希望能够根据注释的值更新不同的图像(参见上面的switch语句)。
用户回调函数与以下序列相关联:
MusicSequenceSetUserCallback(sequence, noteUserCallback, NULL);
上述函数的第三个参数与用户回调函数的void * inClientData参数相关联。
我的问题是,当我尝试从用户回调函数中访问我的视图的IBOutlets时,我不能。为了解决这个问题,我尝试将视图控制器传递给MusicSequenceSetUserCallback函数,如下所示:
MusicSequenceSetUserCallback(sequence, noteUserCallback, self);
我遇到的问题是此 inClientData参数的类型为void ,我无法传入ViewController *对象。当我设置回调函数然后在用户回调函数中再次桥接时,我尝试简单地创建一个桥,但它似乎不起作用。
如果有人对如何实现这一点有任何想法。即使这是一种完全不同的方法,我也会非常感激。
感谢。
修改 的
我尝试了以下内容:
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)
修改 的
将两个桥都更改为__bridge会使错误无效,但仍然无法正常工作; whiteKey60中图像更改的调用不起作用。这不是UIImageView连接的问题,因为在viewDidLoad中做同样的工作正常。
对我而言,似乎正在发生的事情是,自我是否正在履行职能,或者当它通过时可能会破坏连接?
答案 0 :(得分:2)
再次查看MusicSequenceSetUserCallback的声明:
OSStatus MusicSequenceSetUserCallback (
MusicSequence inSequence,
MusicSequenceUserCallback inCallback,
void *inClientData
);
inClientData
的类型不是void
- 这没有意义,C中的变量永远不会有void
的类型。相反,它是void *
- 大致是指向未指定内容的指针。
您需要在进入途中将变量转换为void *
,并在出路时从void *
转换为self
。假设MyClass *
是MusicSequenceSetUserCallback(sequence, noteUserCallback, (void *)self);
,那么:
void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
{
MyClass* self = (MyClass *)inClientData;
...
}
并在回调中:
{{1}}