AVAudioRecorder&调试器停止,没有信号

时间:2011-08-22 06:03:51

标签: objective-c ios ios-simulator avaudiorecorder

我需要用iPhone麦克风录制音频流。 我正在使用AVAudioRecorder。

我在init中初始化AVAR:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [[paths objectAtIndex:0] retain];
NSError *error;
BOOL isDir = NO;
if (! [[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) {
    [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:&error];
}

pathNewFile=  [cachePath stringByAppendingPathComponent:@"123.caf"];

NSLog(@"%@",pathNewFile);

NSDictionary *settings=[[NSDictionary alloc]initWithObjectsAndKeys:
                               [NSNumber numberWithFloat:44100.0f],AVSampleRateKey,
                                    [NSNumber numberWithInt:kAudioFormatAppleLossless],AVFormatIDKey,
                                    [NSNumber numberWithInt:1],AVNumberOfChannelsKey,
                                    [NSNumber numberWithInt:AVAudioQualityMax],AVEncoderAudioQualityKey, nil];
recorder=[[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:pathNewFile] settings:settings error:nil];
[recorder prepareToRecord];

当用户按下rec按钮时,我开始录制:

-(void)recButton:(id)sender{
    NSLog(@"start rec");
        [rootNotesButton setTitle:@"Stop" forState:UIControlStateNormal];
            [rootNotesButton removeTarget:self action:@selector(recButton:) forControlEvents:UIControlEventTouchUpInside];
            [rootNotesButton addTarget:self action:@selector(stopButton:) forControlEvents:UIControlEventTouchUpInside];
            [recorder record];
}

-(void)stopButton:(id)sender{
            NSLog(@"stop rec");
            [rootNotesButton setTitle:@"Play" forState:UIControlStateNormal];
            [rootNotesButton removeTarget:self action:@selector(stopButton:) forControlEvents:UIControlEventTouchUpInside];
            [rootNotesButton addTarget:self action:@selector(playButton:) forControlEvents:UIControlEventTouchUpInside];
            [recorder stop];
}

-(void)playButton:(id)sender{
        NSLog(@"play rec");
            [rootNotesButton setTitle:@"Stop" forState:UIControlStateNormal];
            [rootNotesButton removeTarget:self action:@selector(playButton:) forControlEvents:UIControlEventTouchUpInside];
            [rootNotesButton addTarget:self action:@selector(stopPButton:) forControlEvents:UIControlEventTouchUpInside];

            player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:pathNewFile] error:nil];
            [player play];
}

-(void)stopPButton:(id)sender{
        NSLog(@"Stop play");
            [rootNotesButton setTitle:@"Play" forState:UIControlStateNormal];
            [rootNotesButton removeTarget:self action:@selector(stopPButton:) forControlEvents:UIControlEventTouchUpInside];
            [rootNotesButton addTarget:self action:@selector(playButton:) forControlEvents:UIControlEventTouchUpInside];
            [player stop];
}

但是当我尝试在模拟器中运行我的项目时:我的调试器在字符串上停止: recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:pathNewFile] settings:settings error:nil];没有任何信号或错误。

1 个答案:

答案 0 :(得分:0)

问题似乎是在模拟器中写入cachePath。我试过这个并且有效:

#if TARGET_IPHONE_SIMULATOR
    NSString *cachePath = @"/tmp";
#else
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [[paths objectAtIndex:0] retain];
#endif

你有几个内存泄漏:

  1. 您正在保留cachePath但不会发布它。实际上没有理由保留它。

  2. 您正在player中使用+alloc/-init创建playButton,这意味着您拥有它,但您没有发布它(至少不在发布的代码中)。如果您将其定义为property,则需要使用self.player = …才能正确保留和释放它。

  3. 您正在使用settings创建+alloc/-init但不会发布它。没有理由这样做。您可以这样创建:

  4. NSDictionary *settings=[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithFloat:44100.0f],AVSampleRateKey, [NSNumber numberWithInt:kAudioFormatAppleLossless],AVFormatIDKey, [NSNumber numberWithInt:1],AVNumberOfChannelsKey, [NSNumber numberWithInt:AVAudioQualityMax],AVEncoderAudioQualityKey, nil];

    您需要保留pathNewFile,因为stringByAppendingPathComponent会返回一个自动释放的字符串,而您正在其他类的方法中使用它。