Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

chhoda

macrumors 6502
Original poster
Oct 25, 2008
285
1
in my application I am using 3 sounds, short [8kb, 28kb, 260kb wav files]

I need both of them played quite frequently. So I wrote a singleton class
and initialised all the sounds to SystemSoundID member variables on first init. Then i keep playing them instead of creating SystemSoundID every time.

Now my question is am I leaking here ?

I need to dispose these soundids, on the destruction, especially means when application ends, what would that place be ?

or should I always create SystemSoundID and dispose them by implementing a playFinished callback ?

2 of these sounds are for almost any event in my app so are being used frequently. I think every time creating SystemSoundID and disposing them would be a performance issue.

thanks in advance
CH
Code:
static MySoundClass *mySharedInstance = nil;

@implementation MySoundClass

- (void) playSound:int stype {
	SystemSoundID sid = 0;
	
	switch (stype) {
		case 1:
			sid = oneSoundId;
			break;
		case 2:
			sid = twoSoundId;
			break;
		case 3:
			sid = threeSoundId;
			break;
	}
	
	// Use audio services to play the sound
	AudioServicesPlaySystemSound(sid);
}

- (SystemSoundID) createSoundId:(NSString *)file {
	//Get the filename of the sound file:
	NSString *path = [NSString stringWithFormat:@"%@/%@",
					  [[NSBundle mainBundle] resourcePath],
					  file];
	
	//declare a system sound id
	SystemSoundID soundID = 0;
	
	//Get a URL for the sound file
	NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
	
	//Use audio sevices to create the sound
	OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
	if (error != kAudioServicesNoError)
		NSLog(@"Error creating sound %@", file);
	
	return soundID;
}


- (id) init {
	self = [super init];
	if (self != nil) {
		tapSoundId = [self createSoundId:@"one.wav"];
		shuffledSoundId = [self createSoundId:@"two.wav"];
		finishedSoundId = [self createSoundId:@"three.wav"];
	}
	return self;
}

+ (AMUtility *)sharedInstance {
    @synchronized(self) {
        if (nil == mySharedInstance) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return mySharedInstance;
}


+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (nil == mySharedInstance) {
            mySharedInstance = [super allocWithZone:zone];
            return mySharedInstance;  // assignment and return on first allocation
        }
    }
    return nil; // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;  // denotes an object that cannot be released
}

- (void)release {
    //do nothing
}

- (id)autorelease {
    return self;
}

@end
 
Just a tip to help others help you. Edit your post put place "code" flags around your code. Like so:
Code:
//insert code in between flags
I did that by typing (code) and (/code)-but replace the parenthesis( "(",")" ) with brackets ( "[","]" ).
 
Thanks a lot for the suggestion, somehow in stress(distress rather) ;) I overlooked it
 
What you are doing is fine - you can use the same soundID repeatedly, and it's probably a good idea for common sounds as you said.

When your app closes all memory gets reclaimed, so you will not see a leak. If you wanted to be textbook-correct, you should write a "dealloc" method to call AudioServicesDisposeSystemSoundID on all of your sounds, and then calls [super dealloc].
 
thats the problem, i wrote a -(void) dealloc method, and put a breakpoint in there. when i exit the app it is not hit ! especially in this singleton class !

CH
 
Your dealloc won't automatically get run when the app closes - for most objects it won't run until everyone who alloc'd or retained the object releases it. For a singleton the dealloc will never be run unless you call it yourself, or you create a destroySingleton method that releases the shared instance and sets it to nil.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.