views:

274

answers:

1

I'm hoping someone out there can back me up on this...

I've been working on an application that allows the end user to record a small audio file for later playback and am in the process of testing for memory leaks. I continue to very consistently run into a memory leak when the AVAudioRecorder's "stop" method attempts to close the audio file to which it's been recording. This really seems to be a leak in the framework itself, but if I'm being a bonehead you can tell me.

To illustrate, I've worked up a stripped down test app that does nothing but start/stop a recording w/ the press of a button. For the sake of simplicty, everything happens in app. delegate as follows:

@synthesize audioRecorder, button;
@synthesize window;

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
 // create compplete path to database
 NSString *tempPath = NSTemporaryDirectory();
 NSString *audioFilePath = [tempPath stringByAppendingString:@"/customStatement.caf"];

 // define audio file url
 NSURL *audioFileURL = [[NSURL alloc] initFileURLWithPath:audioFilePath];

 // define audio recorder settings
 NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
      [NSNumber numberWithInt:kAudioFormatAppleIMA4], AVFormatIDKey,
      [NSNumber numberWithInt:1], AVNumberOfChannelsKey,
      [NSNumber numberWithInt:AVAudioQualityLow], AVSampleRateConverterAudioQualityKey,
      [NSNumber numberWithFloat:44100], AVSampleRateKey,
      [NSNumber numberWithInt:8], AVLinearPCMBitDepthKey,
      nil
 ];

 // define audio recorder
 audioRecorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:settings error:nil];
 [audioRecorder setDelegate:self];
 [audioRecorder setMeteringEnabled:YES];
 [audioRecorder prepareToRecord];

 // define record button
 button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
 [button addTarget:self action:@selector(handleTouch_recordButton) forControlEvents:UIControlEventTouchUpInside];
 [button setFrame:CGRectMake(110.0, 217.5, 100.0, 45.0)];
 [button setTitle:@"Record" forState:UIControlStateNormal];
 [button setTitle:@"Stop" forState:UIControlStateSelected];

 // configure the main view controller
 UIViewController *viewController = [[UIViewController alloc] init];
 [viewController.view addSubview:button];

 // add controllers to window
 [window addSubview:viewController.view];
 [window makeKeyAndVisible];

 // release
 [audioFileURL release];
 [settings release];
 [viewController release];

 return YES;
}

- (void) handleTouch_recordButton {
 if ( ![button isSelected] ) {
      [button setSelected:YES];
      [audioRecorder record];

 } else {
      [button setSelected:NO];
      [audioRecorder stop];
 }
}

- (void) dealloc {
 [audioRecorder release];
 [button release];

 [window release];

 [super dealloc];
}

The stack trace from Instruments that shows pretty clearly that the "closeFile" method in the AVFoundation code is leaking...something. You can see a screen shot of the Instruments session here: Developer Forums: AVAudioRecorder Memory Leak

Any thoughts would be greatly appreciated!

A: 

I don't see anything and if Clang doesn't find a leak in your code your code is unlikely to be at fault. It looks like a leak in the framework.

I wouldn't sweat it. A 16 byte leak when the user presses stop isn't likely to cause problem. You would have to stop thousands of recordings before the accumulated leaks grew large enough to cause problems. Small leaks are only a concern when they are rapidly repeated such as in a large loop.

It's annoying and aesthetically repellent to leave a known leak but time is money and I would waste either on this unless you know it is a problem.

TechZen