如何传入一个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 *
。 假设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; ... }