【发布时间】:2012-12-13 08:03:20
【问题描述】:
我已经设置了一个实例变量来引用我用来在不同时间播放不同音频数据的 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,并且还会增加一个。
根据this SO answer,我不应该在这里做任何不同的事情,因为设置 self.player 变量会减少现有值的保留计数。但我也尝试过释放 self.player 并将其设置为 nil,然后再给它一个新值,如this answer 所示,并在设置后自动释放 self.player,如this answer 所示。 (我没有收到初始化播放器的错误,就像最后一个答案中的问题一样。)在所有这些情况下,我的内存使用量一直在上升,并且再也不会下降。
我还需要做些什么来重用每次初始化音频播放器时分配的内存吗?
【问题讨论】:
-
由于您明确调用 release,我假设您没有使用 ARC。在这种情况下,您发布的代码确实会泄漏音频播放器。您应该在分配播放器时自动释放播放器。如果这真的不能解决问题,那么还有其他问题。仪器是否显示泄漏,或者只是内存占用增加?
-
另外,
NSData是从哪里来的?该代码也是可疑的...... -
您对 NSData 的预感很好。事实上,我正在通过从中创建一个新的 NSMutableData 来修剪该数据......我只是编辑了我的答案以表明我的意思。我认为这无关紧要,因为我认为 dataWithData 方法会创建一个自动释放的对象。但是,如果我在此方法结束时手动释放 trimmedData 对象,则内存使用情况如预期:初始化播放器时它会上升,而当播放器停止时它会下降。那么现在,我真的需要自动释放播放器吗?仪器未显示泄漏。
-
嗯,这还是很奇怪。
dataWithData确实返回一个自动释放的对象。您不需要释放它。只有当您第二次致电playAudioData时,您才会正式泄露您的播放器。如果您的播放器从未被解除分配,并且它是该trimmedData的唯一所有者,那么您向其发送额外的release将导致数据被回收,尽管该播放器仍然存在。最后一个挑剔,在您的dealloc中,您应该将self.player设置为nil,而不是显式释放它。 -
这很奇怪。我发现使用 [trimmedData autorelease] 得到的结果与使用 [trimmedData release] 的结果相同。因此,除非我告诉它,否则显然数据不会自动发布。此外,我尝试在每次创建新播放器时手动释放播放器,而不是将其留给自动释放,但手动释放不会回收内存。所以我更新了我的问题以显示唯一对我有用的组合:自动释放播放器而不是手动释放它,并显式自动释放数据而不是依赖正常的自动释放行为。
标签: ios memory-management avaudioplayer