Reputation: 2590
I'm trying to add a custom click sound on all my buttons in my application. I've created a class category for UIButton with the following code in it:
NSURL *soundURL = [NSURL fileURLWithPath:[[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] pathForResource:@"Tock" ofType:@"aiff"]];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
if(audioPlayer == nil){
NSLog(@"%@", [error description]);
} else{
[audioPlayer play];
}
All this is executed in: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
But from what I understand there is a common problem with ARC (wich I am using) here. The audioPlayer objects seems to be released before the sound is played. I've also had a look at AudioServicesPlaySystemSound();
. But that's no alternative for me at the moment because I need a volume level controller in my application and I've found no way to change the system volume without leaving the app.
My question is: Is there any way to make a strong reference to my audioPlayer object in the UIButton class category? Or is there any other, maybe better way, to get this working?
Upvotes: 1
Views: 168
Reputation: 18363
When adding any object relationship in a category, it's always worth looking at associated objects. Use the objc_setAssociatedObject()
and objc_getAssociatedObject()
functions. Make sure to use a unique pointer value for the key, and in your case you'll definitely want to use one of the retain association policies to ensure your object's lifespan is appropriate.
Upvotes: 2