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

时间:2012-03-19 17:43:07

标签: iphone c ios xcode audio

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

对我而言,似乎正在发生的事情是,自我是否正在履行职能,或者当它通过时可能会破坏连接?

1 个答案:

答案 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}}