0

ARCが有効になっています。計測器がメモリ リークを示しています。解決策はありますか?

これが私のコードです:

- (void) onPlayButtonClicked
{
    NSString *title = @"Pause";

if (isPlay) {
    [player stop];
    player.delegate = nil;
    title = @"Play";
}
else
{
    player = [[ReaderGlobals audioPlayer] initWithContentsOfURL:mSoundPath error:nil];
    player.delegate = self;
    [player play];
}

isPlay ^= true;
[mButtonPlay setTitle:title forState:UIControlStateNormal];
}

ReaderGlobalsシングルトンクラスであり[ReaderGlobals audioPlayer]、単一のインスタンスを返しますAVAudioPlayer

4

2 に答える 2

0

Player インスタンスは、再生ボタンを押すたびに作成されます。しかし、それはリリースされていません。プレーヤーをプロパティにします。プレーヤーを停止した後、

self.player = nil;

これは、プレイヤーオブジェクトが軽量オブジェクトであることを理解するのをやめるたびにプレイヤーを解放します。

于 2013-04-19T13:39:31.243 に答える
0

シングルトン[ReaderGlobals audioPlayer]がインスタンスを返す場合、それを呼び出す必要はありませんinitWithContentsOfURL:error:。つまり、AVAudioPlayerが既に割り当てられ (retainCount が 1 に増加)、「初期化」されていることを示しています。したがって、既存の返されたインスタンスに設定する必要があるものを設定するだけです。再度 init を呼び出さないでください。

一般的なベスト プラクティスとして、オブジェクトに対して init を複数回呼び出すべきではありません。保持カウントは増加しませんが (alloc は増加します)、内部 ivar を再作成/リセットする可能性があり、既存の値がリークする可能性があります。

原則として、セッターを使用して値を新しい値 (この場合は URL) にリセットする必要があります。ただし、AVAudioPlayerURL のセッターがないためAVAudioPlayer、別の URL を適用する場合は常に新しいインスタンスを作成する必要があります。そういう使い方が意図されています。

于 2013-04-19T08:35:14.117 に答える