iphone - 从 AVAudioRecorder 播放后 AVAudioPlayer 崩溃

标签 iphone avaudioplayer exc-bad-access avaudiorecorder

我有一个按钮,用户点击即可开始录制,再次点击即可停止。当它停止时,我希望录制的声音“回声”回来,以便用户可以听到录制的内容。第一次这个效果很好。如果我第三次点击该按钮,它会开始新的录制,当我点击停止时,它会崩溃并显示 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/

相关文章:

iphone - iOS 中背景 View 的屏幕截图

ios - 如何标准化分贝值并使其介于 0 和 1 之间

ios - EXC_BAD_ACCESS code=1 UIScrollView 捏合手势崩溃

iphone - 如何在 NSObject 实例中为我的自定义键 (undefinedKey) 设置一个值?

iphone - iOS 谷歌地图公交数据

ios - UIView 的 snapshotView 在没有任何内容的上下文中渲染/绘制

objective-c - [NSKeyedUnarchiver unarchiveObjectWithData :]; 上的 EXC_BAD_ACCESS

xcode - 尝试在 Swift 中播放声音时出现 fatal error

swift - 可以在Apple Watch模拟器中播放音频吗? - Xcode 10.1

objective-c - 我在此Objective-C方法中发生内存泄漏,有人可以告诉我在哪里吗?