2012-03-19 4 views
1

私はMusicPlayer APIを使用していますが、私はユーザーのコールバックで問題を解決しようとしています。voidパラメータのオブジェクトを渡す方法は?

私は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文を参照)。ユーザ・コールバック関数のボイド* inClientDataパラメータに接続された上記機能の

MusicSequenceSetUserCallback(sequence, noteUserCallback, NULL); 

第三のパラメータ:

ユーザのコールバック関数は、このような配列に関連しています。

私の問題は、私は、ユーザーのコールバック関数の中から私の見解のIBOutletsにアクセスしようとすると、私はできないこと、です。

MusicSequenceSetUserCallback(sequence, noteUserCallback, self); 

私が午前問題は、このinClientDataパラメータはvoid型であると私はViewControllerを渡すことができないということです*オブジェクト:この問題を解決するために、私はこのようなMusicSequenceSetUserCallback関数にビューコントローラを渡そうとしました。コールバック関数を設定した後、ユーザーのコールバック関数内で再びブリッジするときにブリッジを作成するだけでしたが、動作していないようです。

誰かが私がこれをどのように達成できるかについての考えがあれば。全く違う方法であっても、本当に感謝しています。

ありがとうございました。

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で画像を変更する呼び出しは機能しません。それはviewDidLoadで同じことをうまく動作させるため、UIImageView接続の問題ではありません。とにかく私には、起こっているように見える何

、自己の機能にそれを作っていないか、またはおそらくそれが渡されたときには、接続を壊すということですか?

答えて

2

再びMusicSequenceSetUserCallbackの宣言を見てみましょう:

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

inClientDataのタイプはvoidではありません - 意味をなさないこと、Cの変数はvoidの型を持つことはできません。むしろ、それはvoid *です - おおよそ、不特定のものへのポインタです。

途中でvoid *に変数をキャストする必要があります。途中でvoid *から変数をキャストする必要があります。

MusicSequenceSetUserCallback(sequence, noteUserCallback, (void *)self); 

とコールバックで:selfと仮定すると、その後、MyClass *ある

void noteUserCallback (void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat) 
{ 
    MyClass* self = (MyClass *)inClientData; 
    ... 
} 
+0

いや、申し訳ありませんが、私はタイプミス。私はそれを前に自己(void *)として渡そうとしましたが、Xcodeは私にそれをすることはできないと言い、代わりにブリッジを使う必要があります。したがって、私は、__ブリッジ(直接変換する)または__bridge_retained(ARCオブジェクトを+1の 'void *'として利用できるようにする)のどちらかを使用することができます。私はどちらを使うべきかわからない。申し訳ありませんが、私は仲間のプログラマーです:Pそして、私はそれを橋渡しすると、通常のようにnoteUserCallback関数で逆参照することができますか? – Barks

+0

ああ、あなたはARCを使用しています - それは比較的新しく、誰もがまだそれを使用していないので、より明示的に述べた方がよいでしょう。私はそれに深く慣れていませんが、普通の '_bridge 'はあなたが望むものだと思っています。両方向です。したがって: '(__bridge void *)self'と' MyClass * self =(__bridge MyClass *)inClientData'です。それを試してみてください。 –

+0

申し訳ありませんが、私は言及すべきでした。私はそれを打つと見てみましょう。 – Barks

関連する問題