我有一个按钮,用户点击即可开始录制,再次点击即可停止。当它停止时,我希望录制的声音“回声”回来,以便用户可以听到录制的内容。第一次这个效果很好。如果我第三次点击该按钮,它会开始新的录制,当我点击停止时,它会崩溃并显示 EXC_BAD_ACCESS。
- (IBAction) readToMeTapped {
if(recording)
{
recording = NO;
[readToMeButton setTitle:@"Stop Recording" forState: UIControlStateNormal ];
NSMutableDictionary *recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
[NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
[NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey,
nil];
// Create a new dated file
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
recordedTmpFile = [NSURL fileURLWithPath:[[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, caldate] retain]];
error = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
[recordSetting release];
if(!recorder){
NSLog(@"recorder: %@ %d %@", [error domain], [error code], [[error userInfo] description]);
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle: @"Warning"
message: [error localizedDescription]
delegate: nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSLog(@"Using File called: %@",recordedTmpFile);
//Setup the recorder to use this file and record to it.
[recorder setDelegate:self];
[recorder prepareToRecord];
[recorder recordForDuration:(NSTimeInterval) 5]; //recording for a limited time
}
else
{ // it crashes the second time it gets here!
recording = YES;
NSLog(@"Recording YES Using File called: %@",recordedTmpFile);
[readToMeButton setTitle:@"Start Recording" forState:UIControlStateNormal ];
[recorder stop]; //Stop the recorder.
//playback recording
AVAudioPlayer * newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:&error];
[recordedTmpFile release];
self.aPlayer = newPlayer;
[newPlayer release];
[aPlayer setDelegate:self];
[aPlayer prepareToPlay];
[aPlayer play];
}
}
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)sender successfully:(BOOL)flag {
NSLog (@"audioRecorderDidFinishRecording:successfully:");
[recorder release];
recorder = nil;
}
检查调试器,它在此处标记错误
@synthesize aPlayer, recorder;
这是我不明白的部分。我认为这可能与释放内存有关,但我一直很小心。我错过了什么吗?
最佳答案
经过一段时间的研究,我偶然发现了这个debugging tip 。它显示 AVAudioPlayer 第二次被释放,导致崩溃。那么代表一定已经完成了清理工作吗?我检查了这个SO线程,建议委托(delegate)不要释放。但是,如果我删除该行
[newPlayer release];
我的程序可以运行了!读完这篇SO线程,我相信我的问题是我应该实现 AVAudioPlayerDelegate 的 - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player success:(BOOL)flag
方法并在声音播放完毕后释放音频播放器。我已经为 AVAudioRecorder 完成了它。
关于iphone - 从 AVAudioRecorder 播放后 AVAudioPlayer 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2742404/