2

私はAVAudioPlayerを利用するために呼び出すクラスを持っていますが、オーディオを再生するにはすべてうまく動作しますが、-audioPlayerDidFinishPlaying:と呼ばれるときに私のNSLog()コマンドはプレーヤーが解放されたことを示します。問題は、後でアプリケーションがクラッシュすることです。私はaudioPlayerがこのクラスの象牙であることを言及する必要があります。ここでは、コードは次のとおりです。audioPlayerDidFinishPlayingの後のEXC_BAD_ACCESS:

-(id) initWithFileName:(NSString *)sndFileName 
{ 
    [super init]; 
    sndFileToPlay = [[NSString alloc] initWithString:sndFileName]; 
    return self; 
} 

-(void)dealloc { 
    [audioPlayer release]; 
    self.audioPlayer.delegate = nil; 
    self.audioPlayer = nil; 
    [super dealloc]; 
} 

-(void)play 
{ 
    [self playSound:sndFileToPlay]; 
} 

-(void)playSound:(NSString *)fileName 
{ 
    NSString *fname, *ext; 
    NSRange range = [fileName rangeOfString:@"."]; 
    int location = range.location; 
    if(location > 0) 
    { 
     fname = [fileName substringWithRange:NSMakeRange(0, location)]; 
     ext = [fileName substringFromIndex:location+1]; 
     [self playSound:fname :ext]; 
    } 
} 

-

-(void)playSound:(NSString *)fileName :(NSString *)fileExt 
{ 
    NSBundle *mainBundle = [NSBundle mainBundle]; 

    NSURL *fileURL = [NSURL fileURLWithPath: 
      [mainBundle pathForResource:fileName ofType:fileExt] isDirectory:NO]; 

    if (fileURL != nil) 
    { 
     audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL 
                  error: nil]; 

     [fileURL release]; 
     [audioPlayer setDelegate:self]; 
     [audioPlayer play]; 
    } 
} 

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player 
         successfully:(BOOL)flag 
{ 
    NSLog(@"Releasing"); 
    [audioPlayer release]; 
} 
+0

質問を編集してフォーマットを修正してください。ありがとう。 – DarkDust

答えて

4

あなたのコードと間違っていくつかのものがあります。 1つの場合

、あなたのdealloc

[audioPlayer release]; 
self.audioPlayer.delegate = nil; 
self.audioPlayer = nil; 

あなたはどのリリースあなたがnilにデリゲートを設定リリース(そしておそらく割り当て解除)選手と、プロパティ、に、そして、audioPlayerをリリースしていますもう一度。 [audioPlayer release];を削除します。

audioPlayerDidFinishPlaying:successfully:でもプレイヤーを解放していますが、変数をnilに設定していません。これは、この変数に再度アクセスするときに別のオブジェクトがそのメモリアドレスに存在する可能性があるため、クラッシュする可能性があります。代わりにプロパティを使用して、あなたのdeallocのようにそれを行う:

self.audioPlayer.delegate = nil; 
self.audioPlayer = nil; 

その後、playSound::に(なんてこった、第二引数非命名!)あなたは上でリリースfileURL-[NSURL fileURLWithPath:isDirectory:]は、自動解放されたオブジェクトを返します。解放しない可能性があります。

最後に、sndFileToPlayのリークがあった場合は、deallocの方法でリリースする必要があります。 sndFileToPlay = [[NSString alloc] initWithString:sndFileName];の代わりに単にsndFileToPlay = [sndFileName copy];を実行してください。

Objective-Cメモリ管理についてお読みになることをお勧めします。 3つか4つのルールを知っているのは難しいことではありません。

+0

ダークダストの指導に感謝します。私はあなたの推奨に従いました(また、playSoundの2番目の引数にも指定されています)、AVPlayerは適切に漏れなくリリースされます。私は、棺の最後の釘がfileURLの過剰リリースだと思います。私はコードから削除した後、かなりスムーズに走った。再度、感謝します! – dman

0

コードをクリーンアップする必要があります。 playSoundが何回か呼び出されると、AVAudioPlayerがリークしています。

あなたのdeallocでは、[audioPlayer release]を2行下に置いてください。

NSZombieEnabledを有効にしてデバッグし、didFinishが呼び出されたときにaudioPlayerが解放されていないことを確認します。

+0

こんにちはAndi、入力いただきありがとうございます。私はDarkDust勧告に従ってdeallocから[audioPlayer release]を削除し、彼が提案した他のエラーを修正したので、彼の答えを受け入れるつもりです。 – dman