Memory Leak - NSString & NSURL - ios

#property ( nonatomic, strong ) NSURL * urlPath;
self.urlPath = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"bark" ofType:#"caf"]];
Running ARC, deployment target 4.3. Instruments gives a leak on the self.urlPath = line.
The self.urlPath is used later on after the view has appeared to setup the AVSoundPlayer. There is NO leak indicated now on the soundplayer, only on this NSURL line. The audio plays, but when the view is pop'd a memory leak occurs.
Any ideas as I've been at this > 12hrs now...

Seems to be a memory leak in Core Foundation only in iOS 6.
Therefore filed as a bug:
Bug ID# 12699818.

Your player is leaking, and if your player leaks, every player will keep their URL and string object too.
self.player = [[[AVAudioPlayer alloc] initWithContentsOfURL:pingURL error:nil] autorelease];
If you declared player as a retaining property, then
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:pingURL error:nil];
will leave the reference count at 2.
self.player = nil;
will make it 1.

Related

Audio wont play in objective c

I have the following code that used to work to play a sound in my project however after iv done some playing around over the past few weeks on other aspects of the project it dose not seem to play.
The audio file is in the main directory and works in preview.
Any ideas?
//playsound
AVAudioPlayer *showsound;
NSString *audiopath = [[NSBundle mainBundle] pathForResource:#"mouse1" ofType:#"wav"];
NSURL *audiourl = [NSURL fileURLWithPath:audiopath];
showsound = [[AVAudioPlayer alloc]initWithContentsOfURL:audiourl error:Nil];
[showsound play];
It's because after the line showsound play your method comes to an end and showsound (your AVAudioPlayer) is released. Hence there is nothing to do any playing any more. Solution: retain it! (For example, set an instance variable to hold on to it.)

Xcode Exception Breakpoint Always Pauses On Property

This has driven me nuts for a long time now. I am using Xcode 4.6 but this has been happening for several versions. When I turn on breakpoints and add the Exception Breakpoint, it always pauses on a line of code where I'm setting up an audio player. I set some up before and after the same way, but it only pauses on that one.
Here is the code I'm using:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
self.playedSongs = [NSMutableSet setWithCapacity:9];
[self loadSettingsFromFile];
NSURL *sfxPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Snap.aiff" ofType:nil]];
self.snapSfx = [[[AVAudioPlayer alloc]initWithContentsOfURL:sfxPath error:nil]autorelease];
self.snapSfx.volume = 1.f;
NSURL *fireworksPath;
if ([OriginalIPadChecker isNotiPadOriginal]) {
fireworksPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"FireworksSFX.mp3" ofType:nil]];
}
else{
fireworksPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"NoFireworksSFX.mp3" ofType:nil]];
}
self.fireWorksSfx = [[[AVAudioPlayer alloc]initWithContentsOfURL:fireworksPath error:nil]autorelease];
self.fireWorksSfx.volume = 1.f;
NSURL *poofPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Remove Poof.mp3" ofType:nil]];
//The line below is the one that it pauses on
self.removePoof = [[[AVAudioPlayer alloc]initWithContentsOfURL:poofPath error:nil]autorelease];
self.removePoof.volume = 1.f;
NSURL *newHighScorePath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"New High Score.mp3" ofType:nil]];
self.theNewHighScore = [[[AVAudioPlayer alloc]initWithContentsOfURL:newHighScorePath error:nil]autorelease];
self.theNewHighScore.volume = 1.f;
NSURL *badgeInTrophyPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Badge In Trophy.aiff" ofType:nil]];
self.badgeInTrophy = [[[AVAudioPlayer alloc]initWithContentsOfURL:badgeInTrophyPath error:nil]autorelease];
self.badgeInTrophy.volume = 1.f;
NSURL *dingPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Ding.aif" ofType:nil]];
self.ding = [[[AVAudioPlayer alloc]initWithContentsOfURL:dingPath error:nil]autorelease];
self.ding.volume = 1.f;
The app doesn't crash and the sound plays fine, but the debugger always pauses on that one line—even if I move it somewhere else, it still pauses. I can continue the execution and it works just fine, but this really bugs me.
I don't get why it pauses. Any ideas?
As explained in the comment of Xcode stops on prepareToPlay, the reason for the breakpoint is that you were setting a generic breakpoint of type 'exception on All' which responds to a signal which is fired by the c++ library. It is better to use an "Objective-c" exception breakpoint, which will protect for such cases.
Try this and update the question on where it stops (if it stops):
AVAudioPlayer *foo;
NSError *error = nil;
assert(poofPath);
foo = [AVAudioPlayer alloc];
foo = [foo initWithContentsOfURL:poofPath error:&error];
assert(foo);
[self setRemovePoof:foo];
[foo release];
If the assert kicks in, that's probably an Apple issue. Unfortunately there are cases of Apple internal frameworks using try/catch, and they will trigger the breakpoint. Its not common but does happen.
If in the end that foo is not nil and the error is also nil, the best you can do is enter a bug report at bugreporter.apple.com (which would be great). Also, did you look at poofPath - is there any chance that the URL returns anything other than pristine audio?
My guess is that Apple tries to open and process the file, its gets an internal exception because there is something "odd" or abnormal about the file. Then the framework does additional work, and manages to read the file. So you get your sound but the exception too. Take some common type of mp3 and put that in your app bundle, and try to open it. See if it (and maybe a few other files) gives the same error. Or create a demo project with the sound and upload it (in the end you may need to submit the demo project to Apple in a bug report). These kinds of things should be bug reported.
EDIT: Unfortunately there are cases of Apple internal frameworks using try/catch, and they will trigger the breakpoint. Then, as mentioned earlier, some later code finally figures out how to decode the file and does.
The original poster has responded in a comment that this particular file was created with Audacity, and has heard that such files often have decode issues.

Xcode AVAudioPlayer isn't playing

I have a ViewController : GLKViewController
with this code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"background-music-aac" ofType:#"caf"];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithData:data error:nil];
audio.delegate = self;
audio.volume = 1.0;
audio.numberOfLoops = -1;
[audio prepareToPlay];
[audio play];
[self setupContext];
[self setupDisplay];
}
However... my graphical things working fine but the iOS simulator plays no music.
did I something wrong?
Assuming you are using ARC, the player is getting deallocated as soon your method returns to its caller. To quote from this answer:
ARC inserts a release call to the audio player, so it's deallocated right after leaving the method where it is created.
Try implementing the AVAudioPlayer as a property.
If your data is nil, the file was not properly added to the project. To add your file to the project, just drag and drop it and add it to your targets.
Also, AVAudioPlayer has a method, initWithContentsOfURL:, which you might want to use.

AVAudioPlayer: Simple sound not playing

I'm trying to figure out why sounds aren't playing in my app, so I created what I think is as simple an implementation as possible:
NSError *error;
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"canary-trills" ofType:#"wav"];
NSLog(#"string=%#", soundFilePath);
NSURL *url = [[NSURL alloc] initFileURLWithPath:soundFilePath];
NSLog(#"URL=%#", url);
AVAudioPlayer *avPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url error:&error];
[avPlayer prepareToPlay];
BOOL success = [avPlayer play];
NSLog(#"The sound %# play", success ? #"did" : #"didn't");
Per the console, it looks like it finds the resource, creates the URL correctly. Even the play call indicates success. However, no sound play in the simulator nor the device.
AVAudioPlayer wasn't being retained & was going out of scope.
Adding:
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
to the class & using that member solved the issue.

Should I release NSBundle in sound?

Should I release NSBundle in the below code or not? NSURL should also be release or not?
I am confused.
NSBundle *mainBundle = [NSBundle mainBundle];
NSError *error;
NSURL *audioURL = [NSURL fileURLWithPath:[mainBundle pathForResource:#"count_in" ofType: #"mp3"]];
AVAudioPlayer *player1 = [(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
self.player = player1;
[self.player play];
[player1 release];
You should not release NSBundle and NSURL instances because you haven't alloced these.
From the apple Documentation.
You take ownership of an object if you create it using a method whose
name begins with “alloc”, “new”,
“copy”, or “mutableCopy” (for example,
alloc, newObject, or mutableCopy), or
if you send it a retain message.
You use release or autorelease to relinquish ownership of an object.
autorelease just means “send a release
message in the future” (specifically:
when the used autorelease pool
receives a drain message—to understand
when this will be, see “Autorelease
Pools”).
I would highly recommend you to clear your memory management concept.
Read the apple article on
Memory Management Rules

Resources