2011-12-16 1 views
1

この質問の原因は、this questionへの回答にあります。音声が完成すると、navigationControllerにアクセスするとEXC_BAD_ACCESSが返されます

私は自分のViewControllerによって管理される一連のパズルを持っています。 >メニュービューコントローラ - - >ルーティングビューコントローラ - >ランダムに選択されたパズルビューコントローラ

「ルーティング・ビュー・コントローラは、」ランダムにプッシュするパズルのビューコントローラを選択

UINavigationViewController:ワークフローは、このようになります。スタック誰かがパズルを解決したら、私は "あなたが勝つ"オーディオサンプルを再生し、次にスタックからビューコントローラをポップします。その時点でRouting View Controllerはランダムに次のパズルを選択します。ここでは、サウンドを再生するため、スタックオフパズル・ビュー・コントローラをポップのための私のコードは次のとおりです。

-(void) playSound:(SystemSoundID)soundID withClientData:(UIViewController*)clientData { 
    soundIsPlaying = true; 

    if (clientData) 
     AudioServicesAddSystemSoundCompletion(soundID, nil, nil, soundFinishedPlaying, (__bridge void *)clientData); 
    else 
     AudioServicesAddSystemSoundCompletion(soundID, nil, nil, soundFinishedPlaying, nil); 

    AudioServicesPlaySystemSound(soundID); 
} 

void soundFinishedPlaying(SystemSoundID ssID, void *clientData) 
{ 
    soundIsPlaying = false; 

    if(clientData) { 
     NSLog(@"clientData not null!"); 
     UINavigationController * navController = ((__bridge UIViewController *) clientData).navigationController; 
     if (navController){ 
      NSLog(@"navController not null!"); 
      [navController popViewControllerAnimated:false]; 
     } else { 
      NSLog(@"NavController was nil!"); 
     } 
    } 

} 

二パズルは、私がsoundFinishedPlaying内のコード行にスローEXC_BAD_ACCESSエラーを得る解消した後、問題がある:

UINavigationController * navController = ((__bridge UIViewController *) clientData).navigationController; 

このコード行をデバッグすると、clientDataにUINavigationControllerへの参照があることがわかります。なぜこのエラーが表示されているのか少し疑問に思っています。

私はsoundFinishedPlayingのストレートC関数を指定する必要があるという事実や、実際にはUIViewControllerリファレンスをvoid *として渡す必要があるという事実と関係があると思われます。

オーディオクリップの再生が完了したら、どこに間違っているのか、またはビューの切り替えをトリガーする良い方法があるか教えてください。前もって感謝します!

答えて

1

ここで何が起こっているのか分かりました。問題は、私はこのラインでやった「ブリッジ」キャストしていた:私はNavigationControllerの私のインスタンスは、音の完了方法が完了した後まで、間接参照されないことが保証することを代わりに__bridge_retainedするためのブリッジモードを変更した場合

AudioServicesAddSystemSoundCompletion(soundID, nil, nil, soundFinishedPlaying, (__bridge void *)clientData); 

。 __bridge_retainedを使用することで、soundFinishedPlayingでCFRelease(...)を使用してポイントを明示的に逆参照する必要があることも意味します。

私はまだ私はここに詳細が入力すること自由に感じ欠けているので、もし他のメモリリークが存在しないことを確認するために、アップルのコード分析ツールにランプアップしています。

FYI ...おかげthis post私は正しい方向に向いています。

関連する問題