7

AVAudioPlayerに関連する奇妙なメモリリークの問題で立ち往生しており、頭に浮かんだすべてを試した後、助けが必要です。

問題の簡単な説明は次のとおりです-コードは直後に表示されます。プレーヤーを初期化し、サウンドトラックを無限ループで再生し始めます(無限ループまたは1回の再生で問題は変わりませんでした)。音楽が始まってから数秒後、別のサウンドトラックに切り替えます。そのため、新しいプレーヤーを作成して初期化し、古いプレーヤー(再生中)を解放してから、新しいプレーヤーを所定の位置にセットして再生します。

その時点で(新しいプレーヤーを呼び出した直後-[プレーヤーの再生])、メモリリーク(3.5Kb)が発生します。

私は次のことを試しました:

  • 古いプレーヤーを停止してから放します-効果はありません

  • 再生指示の直後にプレーヤーを解放します-再生を開始しませんでした

  • 古いプレーヤーを2回解放します-クラッシュ

  • 最初のプレーヤーを作成して再生しても、メモリリークは発生しません。

また、リファレンスでは、「play」は非同期であると記載されているため、おそらくrefカウントが1増加しますが、この場合、[Playerstop]が役に立たなかったのはなぜですか。

ありがとう、

これが私がそれをどのように使うかについてのコードのいくつかの部分です:

- (void) loadAndActivateAudioFunction {
NSBundle        *mainBundle = [NSBundle mainBundle];
NSError         *error;
NSURL           *audioURL = [NSURL fileURLWithPath:[mainBundle pathForResource: Name ofType: Type]];
AVAudioPlayer   *player = [(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];

if (!player) {
    DebugLog(@"Audio Load Error: no Player: %@", [error localizedDescription]);
    DuringAudioPrep = false;
    return;
}
[self lock];
[self setAudioPlayer: player];
[self ActivateAudioFunction];
[self unlock];

}

- (void) setAudioPlayer : (AVAudioPlayer *) player {
if (Player)
{
    if ([Player isPlaying] || Repeat)  // The indication was off???
        [Player stop];
    [Player release];
}
Player = player;

}

- (void) ActivateAudioFunction {
[Player setVolume: Volume];
[Player setNumberOfLoops: Repeat];    
[Player play];

DuringAudioPrep = false;

}

4

4 に答える 4

7

メモリリークを起こさずに AVAudioPlayer を作成する方法を次に示します。 説明については、このページを参照してください

これにより、AVAudioPlayer リークが 100% 除去されたことをアプリで確認しました。

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path {
    NSData *audioData = [NSData dataWithContentsOfFile:path];
    AVAudioPlayer *player = [AVAudioPlayer alloc];
    if([player initWithData:audioData error:NULL]) {
        [player autorelease];
    } else {
        [player release];
        player = nil;
    }
    return player;
}
于 2009-11-19T19:44:58.227 に答える
2

プロトコル AVAudioPlayerDelegate とそのメソッド audioPlayerDidFinishPlaying:successfully: を実装してから、オーディオ プレーヤー オブジェクトを解放します。

例えば。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [player release]; // releases the player object
}
于 2011-06-30T21:33:32.317 に答える
0

私が見た限り、あなたのコードは私には問題ないように見えるので、問題を引き起こしているコードが他の場所にある可能性があります。

私はあなたが一種の奇妙なイディオムを使っていると言います. 作成を保持してセットでリリースするのではなく、次のようにします。

    // new players will always be created autoreleased.
    AVAudioPlayer   *player = [[(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error] autorelease];

- (void) setAudioPlayer : (AVAudioPlayer *) player 
{
  if (Player)
  {
      if ([Player isPlaying] || Repeat)  // The indication was off???
            [Player stop];
        [Player release];
  }
  Player = [player retain];
}

このようにして、実際に setAudioPlayer メソッドに入ったときに「プレーヤー」オブジェクトのみを保持するため、追跡が容易になる場合があります。

また、リークしているのが実際に AVAudioPlayer オブジェクトであることを確認します。楽器はこれを確認できるはずです。

于 2009-08-30T13:11:52.373 に答える
-2

プロジェクトに MediaPlayer.framework を追加してみてください

于 2009-11-25T11:46:05.183 に答える