如何传入一个void参数的对象?

我正在使用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中做同样的工作正常。

对我而言,似乎正在发生的事情是,自我没有实现这个function,或者当它通过时它可能会破坏连接?

再看一下MusicSequenceSetUserCallback的声明:

 OSStatus MusicSequenceSetUserCallback ( MusicSequence inSequence, MusicSequenceUserCallback inCallback, void *inClientData ); 

inClientData的类型不是void – 这没有意义,C中的变量永远不会有一种void 。 相反,它是void * – 粗略地,指向未指定的东西的指针。

你需要在进入的路上将变量转换为void * ,并在出路时将void *void * 。 假设selfMyClass * ,那么:

 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; ... }