4

さまざまな時間にさまざまなオーディオ データを再生するために使用している AVAudioPlayer を参照するインスタンス変数を設定しました。私のヘッダーファイルには以下が含まれています:

AVAudioPlayer *player;

@property (nonatomic, retain) AVAudioPlayer *player;

そして私の実装ファイルには以下が含まれています:

- (void)playAudioData:(NSData *)data {
    NSMutableData *trimmedData = [NSMutableData dataWithData:data];
    int duration = 2; // seconds
    int dataLength = duration * 2 * 44100; // assumes 16-bit mono data
    [trimmedData setLength:dataLength];

    NSError *playerError;
    self.player = [[AVAudioPlayer alloc] initWithData:trimmedData error:&playerError];
    [self.player autorelease]; // ADDED
    if (playerError) {
        NSLog(@"player error: %@", playerError);
    }
    [self.player play];
    if (([[[UIDevice currentDevice] systemVersion] compare:@"6.0"] != NSOrderedAscending)&&([[[UIDevice currentDevice] systemVersion] compare:@"6.1"] == NSOrderedAscending)) {
        [trimmedData autorelease]; // ADDED
    }
}

- (void)dealloc {
    [self.player release];
}

アプリのメモリ使用量をプロファイリングしているときに、このメソッドを呼び出すと、ライブ バイトが 500k 増加することに気付きました。これは、再生しているオーディオ データのサイズとほぼ同じです。ただし、メソッドを再度呼び出すと、メソッドを呼び出すたびに、ライブ バイトがさらに 500k ずつ増加します。

この SO answerによると、 self.player 変数を設定すると既存の値の保持カウントが減少するため、ここで別のことを行う必要はありません。しかし、この回答に示すように、新しい値を与える前に self.player を解放して nil に設定し、この回答に示すように、設定後に self.player を自動解放しようとしました。(最後の回答の問題のように、プレーヤーの初期化でエラーが発生することはありません。)これらすべてのケースで、メモリ使用量は増え続け、二度と減ることはありません。

オーディオ プレーヤーを初期化するたびに割り当てられるメモリを再利用するために、他に何かする必要がありますか?

4

1 に答える 1

0

[ARC]に切り替える前にアプリで同じ問題がAutomatic Reference Counting発生しました。アプリがクラッシュするまでメモリ使用量が増加しますよね?. この問題を解決するための最速の方法は、アプリ/プロジェクトでも ARC を使用することです。実際、ARC は必要に応じてメモリとリリースを管理するすべての作業を行います [ ARC を使用する場合、コードにAVAudioPlayerは何も必要ありません]。 -void(dealloc)、これ以上のリークはありません:-)。ARC がわからない場合は、次のリンクも確認できます。

http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1

ヘッダ:

#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>

@interface YourViewController : UIViewController <AVAudioPlayerDelegate>
{
    AVAudioPlayer           *player;

    /* Your other code here */
}

/* Your other code here */

@end

主要:

#import "YourViewController.h"

@implementation YourViewController

/* Your other code here */

- (void)playAudioData:(NSData *)data
{
    NSError *playerError;
    self.player = [[AVAudioPlayer alloc] initWithData:data error:&playerError]; error:NULL];

    if (playerError)
    {
        NSLog(@"player error: %@", playerError);
    }

    [self.player play];

    /* No more need to release AVAudioPlayer, ARC will do the job */

}

/* Your other code here */

@end
于 2012-12-28T00:47:09.400 に答える