4

AudioToolBoxを使用して音楽を再生すると、メモリリークが大きくなります。

AVAudioPlayer *newMusicPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];

このコードを使用して音楽を再生します。iOS5およびiOS4では、正しく機能します。しかし、iOS6では、データのサイズが5Mの場合、5Mすべてがリークしました。また、Instrumentsでリーク情報を確認できません。

同じ問題を抱えている人はいますか?どんな提案でもありがたいです。

ここにあるすべてのオーディオコード(ARCを使用):

@implementation ViewController
{
    AVAudioPlayer *_player;
}

- (void)play
{
    if (_player)
    {
        [_player stop];
        _player = nil;
    }

    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"test.app/1.mp3"];
    NSData *musicData = [[NSData alloc] initWithContentsOfFile:path];
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:musicData error:nil];
    player.volume = 1;
    if (player)
    {
        _player = player;
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(100, 100, 100, 100);
    [button setTitle:@"play" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(play) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

@end
4

2 に答える 2

5

を使用してファイルからオーディオを再生していますAVAudioPlayerが、iOSシミュレーターが常にメモリをリークしていることがわかりましたが、デバイスはリークしていません。これは、Instrumentsを使用して確認されました。これはARCコードです。

私のプレーヤーは次のように宣言されています:

@property (nonatomic, retain) AVAudioPlayer *numberPlayer;

そしてこのように合成されます:

@synthesize numberPlayer = _numberPlayer;

いくつかの異なるサウンドを再生する必要がありAVAudioPlayer、作成後に別のオーディオファイルを再生するようにリセットできないため、次のように毎回新しいプレーヤーを作成しています。

NSString *audioFilePathName = [NSString stringWithFormat:@"Voices/%@/%03i.m4a", self.voiceName, self.theNumber];
NSURL *url = [NSURL fileURLWithPath:BUNDLE_FULL_PATH(audioFilePathName)];
self.numberPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
self.numberPlayer.numberOfLoops = 0;
[self.numberPlayer setCurrentTime:0.0];
[self.numberPlayer setDelegate:self];
[self.numberPlayer prepareToPlay];
[self.numberPlayer play];

デリゲートでは、プレーヤーのnil再生が終了したときにプレーヤーを設定しました。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    if (player == self.numberPlayer) {
        _numberPlayer = nil;
    }
}

シミュレータでは、AudioSessionDeviceUISoundNewDeviceリークメモリの両方。ただし、最大の漏洩者は実際にはNSURLです。これらのリークはデバイスで発生しません。この動作はiOS6でも変更されていませんが、プロジェクトの展開を5.0に設定しているので、違いが生じます。

https://stackoverflow.com/questions/3433487/avaudioplayer-leak-in-simulatorおよびAudioToolboxライブラリAVAudioPlayerのメモリリークも参照してください。

于 2012-09-24T05:39:24.530 に答える
1

たぶんあなたは私よりも上手くやっていて、私は私の前にXCodeを持っていませんが:

オブジェクトが作成され、参照が作成されました:

AVAudioPlayer *newMusicPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];

これは割り当てであり、割り当てではなく、保持されません。

_musicPlayer = newMusicPlayer;

関数外でplayMusicWithMusicDataは、の割り当てが解除さnewMusicPlayerれ、を使用すると他の関数でコードがクラッシュします_musicPlayer。アナライザーツールは、私が保持したのと同じくらい、おそらくリリースもしつこくなりました。

ios4を使用している場合は、このプロジェクトのARCではありません。

ifブランチ:

    [_musicPlayer stop];
    _musicPlayer = nil;

_musicPlayerがゼロでないことを確認しますが、それでは問題は解決しません。

それがどこにあるのか見当がつかない、iOSにない場合、おそらくそこにあるでしょう:

自分ではなく代理人を変更した場合は解決しました。

 _musicPlayer.delegate = self;

他のクラスに?

于 2012-09-23T15:54:33.877 に答える