Ios ivar中AVAudioPlayer的内存未被重用

Ios ivar中AVAudioPlayer的内存未被重用,ios,memory-management,avaudioplayer,Ios,Memory Management,Avaudioplayer,我已经设置了一个实例变量来引用我用来在不同时间播放不同音频数据的AVAudioPlayer。我的头文件包含: AVAudioPlayer *player; - (void)playAudioData:(NSData *)data { NSMutableData *trimmedData = [NSMutableData dataWithData:data]; int duration = 2; // seconds int dataLength = duration *

我已经设置了一个实例变量来引用我用来在不同时间播放不同音频数据的AVAudioPlayer。我的头文件包含:

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];
}

我的实现文件包含:

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

根据,我不应该在这里做任何不同的事情,因为设置self.player变量会减少现有值的保留计数。但我也尝试在给它一个新值之前释放self.player并将其设置为零,如中所示,并在设置后自动释放self.player,如中所示。(我没有收到初始化播放器的错误,就像上次回答中的问题一样。)在所有这些情况下,我的内存使用率一直在上升,再也不会下降


每次初始化音频播放器时,我是否需要执行其他操作来重新使用分配的内存?

在切换到
自动参考计数之前,我的应用程序也有同样的问题,内存使用将增加,直到应用程序崩溃,对吧?。解决此问题的最快方法是在应用程序/项目中也使用ARC,事实上,它将完成管理内存的所有工作,并在需要时释放
AVAudioPlayer
[如果使用ARC,您不需要在代码中使用任何
-void(dealoc)
,因此不再泄漏:-)。如果您不知道ARC是什么,也可以检查此链接:

标题:

#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

既然您显式地调用了release,我假设您没有使用ARC。在这种情况下,您发布的代码确实会泄漏音频播放器。你应该在分配玩家时自动释放它。如果这真的不能解决问题,那么还有其他问题。仪器是否显示泄漏,或者只是内存占用增加?另外,这
NSData
来自哪里?该代码也是可疑的…你对NSData的预感很好。事实上,我正在通过创建一个新的NSMutableData来修剪这些数据。。。我只是编辑了我的答案来说明我的意思。我认为这与此无关,因为我认为dataWithData方法将创建一个自动删除的对象。但是,如果在该方法结束时手动释放trimmedData对象,内存使用情况将与预期一样:初始化播放机时内存使用情况会上升,而在播放机停止时内存使用情况会下降。那么现在,我真的需要自动释放玩家吗?仪器没有泄漏,这还是很奇怪的
dataWithData
确实返回自动删除的对象。你不需要释放它。只有当你第二次打电话给playAudioData时,你才会正式泄露你的播放器。如果您的播放器从未被解除分配,并且它是该
trimmedData
的唯一所有者,则您向其发送额外的
版本将导致数据被回收,尽管该播放器仍在使用。最后一个吹毛求疵的地方是,在你的
dealoc
中,你应该将
self.player
设置为
nil
,而不是明确地释放它。这很奇怪。我发现我使用[trimmedData autorelease]得到的结果与使用[trimmedData release]得到的结果相同。显然,除非我告诉它,否则数据不会自动恢复。此外,我试图在每次创建新播放器时手动释放该播放器,而不是将其留给自动释放,但手动释放不会回收内存。所以我更新了我的问题,以显示对我有效的唯一组合:自动释放播放器而不是手动释放,以及显式自动释放数据而不是依赖正常的自动释放行为。呃。。。这难道不需要对我已经庞大而复杂的应用程序进行重大修改吗?@arlomedia你可以尝试使用XCode的自动转换,它只需点击几下就可以将你的代码转换成支持ARC的代码,并且完全自动[它还将删除不必要的代码,如“release”],在链接中,前面有一段关于这一点的内容“自动转换”检查:-)。XCode也会为您的项目创建一个快照,因此如果您对ARC不满意,您可以立即恢复所有更改。自动转换工具也非常好用!