tags:

views:

27

answers:

1

I've taken over a code base that has subtle flaws - audio player goes mute, unlogged crashes, odd behavior, etc.

I found a way to provoke one instance of the problem and tracked it to this code snippet:

- (void)playNextArrayObject {

NSURL *soundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]
  pathForResource:[[soundsToPlay objectAtIndex:count] description] 
  ofType:@"mp3"]];
self.audioPlayer = nil;

self.audioPlayer = [[AVAudioPlayer alloc] 
  initWithContentsOfURL:soundURL error:nil];

self.audioPlayer.delegate = self;
AudioSessionSetActive(YES);
[audioPlayer play];
}

When I comment out the 2nd line (nil) and add a release to the end, this problem stops.

[self.audioPlayer release];
  1. Where do I go from here?
  2. Nils are used in a similar fashion throughout the code (and may cause similar problems) - is there a safe way to remove them?
  3. I'm new to memory management - how can I discern proper nil usage from bad nil usage?
+1  A: 

Your change is correct - the =nil line is a noop, and the release is necessary following the alloc/init. Using self.something = nil can be good practice; it releases the current value of a property, and makes sure that you can't make invalid access to the freed memory.

Good memory management is simple. But you should read the Cocoa Memory Management Guide for explicit instructions.

Paul Lynch
The =nil doesn't release (as I thought it might). I tried it in place of the release, but hit the bug.
BankStrong
It does - it releases the previous value of the property, which is why it is redundant, as the assignment on the next line does exactly the same (as well as making the assignment). Replacing the final (missing) release could cause other problems if the property is referenced elsewhere.
Paul Lynch
Makes sense now - thank you for the explanation.
BankStrong