1

iPhone/Mac "play a sound class": link text

I find an awful lot of great objective-c classes and code samples here... and elsewhere.

I successfully create the .h and .m files, but how do I call them from my existing code?

  • Where do I put the @class or #import statements?
  • How do I call the methods?
  • What if I need to play 2-3 different sounds files?
  • Why include the code... without any info about how to ever use it anywhere?
Community
  • 1
  • 1
Annette
  • 127
  • 2
  • 8

2 Answers2

1

Usually Annette, you can tell what needs to be done by looking at the objects superclass

in this case, if you look at the .h file you can see @interface Sound : NSObject

Sound is the name of this Class, NSObject is our superclass

the initWithPath method is returning itself and does a [super init] meaning that it calls the parents init method.

In order for you to call this methods theres one of two ways.

You can have a property that you manage lets say, in your delegate.

@class Sound;
@interface ScanViewController : UIViewController  {
    Sound *aSound;
}
@property (nonatomic, retain) Sound *aSound;

then somwhere in your delegate

- (void) someFunction() {
   aSound = [[Sound alloc] initWithPath:@"pathtoSound"];
}

If you didnt want it to be a property you can easily create a new Sound object anywhere in a .m file like so.

Sound *mySound = [[Sound alloc] initWithPath:@"pathtoSound"];

If you wanted multiple sounds, Store them in a Sound Array

P.S. dont forget to release these objects since you alloc'ed them.

Kyle Browning
  • 5,374
  • 1
  • 19
  • 30
0

Wherever you want to call a method from one of the classes, put #import "SomeClass.h" at the top of the .h file.

Then you can do [SomeClass someMethod] or SomeClass *object = [[SomeClass alloc] init], or whatever you want to do.

This is pretty basic, you should read through The Objective-C Programming Language Guide

Kurbz
  • 11,003
  • 2
  • 17
  • 12
  • I've read that... and many others... several times. No place do I find it all just "spelled out clearly". Maybe because there are so many different ways to do it... and no 1 way is "correct". So I don't have to use @class ever? – Annette Jul 23 '10 at 14:26
  • I managed to get things to compile without any errors... and it seems to work... (So I know I'm 99% sucessful)... but "build and analyze" seems to alway report a memory leak on this line: aSound = [[Sound alloc] initWithPath:@"pathtoSound"]; – Annette Jul 23 '10 at 14:28
  • @class vs. #import: http://stackoverflow.com/questions/322597/objective-c-class-vs-import – Kurbz Jul 23 '10 at 14:29
  • Regarding the memory leak, you have to release the object once you're done with it. – Kurbz Jul 23 '10 at 14:30
  • It is released in my file.m dealloc with: [mySound release]; (But "build and analyze" reports a leak right when I alloc it anyway.) I've done a clean-all several times. And since I didn't really do anything wildly-tricky... I would think "build and analyze" would easy see my "dealloc/release". – Annette Jul 23 '10 at 14:36
  • For the method where you alloc the object, is it ever called more than once? – Kurbz Jul 23 '10 at 14:39
  • Well even if it isn't, it still has the possibility of being called more than once so that's probably why you're getting a leak. Can you post the code you have so far? – Kurbz Jul 23 '10 at 14:45
  • No one mentioned that. (Is there a way to learn the-exact-way-with-everything-mentioned-in-one-list?) What is a good way to ensure it's only called once? It reports a memory-leak with (or without) a line before my alloc, such as: if(mySound == nil) // Only alloc once, here – Annette Jul 23 '10 at 14:47
  • Well you should do something like this: - (void) someFunction() { aSound = [[Sound alloc] initWithPath:@"pathtoSound"]; //do something with the aSound; [aSound release]; } – Kurbz Jul 23 '10 at 14:54
  • I need this sound only in 1 place... but I need to very often there. So I didn't want to alloc/release it many times. Or should I? – Annette Jul 23 '10 at 14:55
  • I didn't want to alloc in my app-delegate... since I only need to play this sound in 1 of my classes. – Annette Jul 23 '10 at 14:56
  • Every time you alloc, you need to release, it's perfectly fine to do that. No you don't need it in the delegate. If you only have one sound object, you could define it in the class and alloc it in the -init, then just release it in dealloc. – Kurbz Jul 23 '10 at 14:57
  • Is there a code-sample that shows actual code: "This is how you install this sound-class in your code" (It would be SO much easier than all this trial-and-error and guessing.) – Annette Jul 23 '10 at 14:57
  • It's only a short 0.5 second sound file. But it might get played over and over very quickly by the user (think of a fire-button in a game). I was trying to avoid loading it... alloc it... play it... free it.... 1000 times. Instead: load it ONCE. alloc it ONCE. Play it 1000 times. Then free it ONCE. Is that not a good plan? – Annette Jul 23 '10 at 15:00
  • A quick google turned up this... http://iphoneincubator.com/blog/tutorial/how-to-play-audio-with-the-iphone-sdk – Kurbz Jul 23 '10 at 15:00
  • This is actually exactly what you want: http://howtomakeiphoneapps.com/2009/08/how-to-play-a-short-sound-in-iphone-code/ – Kurbz Jul 23 '10 at 15:01
  • I notice his example didn't alloc or free anything anywhere. How is that possible? (Why do I even struggle with memory-issues when you can also do it a totally-memory-alloc'less way???) Also... wouldn't it be VERY slow and inefficient the way he does it: Search the bundle 1000 times. Find the sound-file 1000 times. Load it into memory 1000 times. Create it 1000 times. Play it 1000 times. – Annette Jul 23 '10 at 15:09
  • Because he's using some framework, you had no choice but to alloc with the sample code you were using. – Kurbz Jul 23 '10 at 15:13
  • The iphoneincubator.com code always is now marked "outdated" by its author. (Not sure what that means... but I think I should avoid 'learning' from outdated examples.) – Annette Jul 23 '10 at 15:28
  • Let me ask this way: If you *HAD TO* put your sound-alloc line in your viewWillAppear or viewDidLoad methods... how would you do it? (The reasons I need it inside 1 of those 2 are too long to post here... but I will if you need to know them.) Where is the "put it here to ensure it only runs once" part of my code? But I thought that's what "if(mySound == nil)" would help ensure... no matter WHERE I put the code. It will always only alloc ONCE. No? – Annette Jul 23 '10 at 15:35
  • In the .h do Sound *mySound (With the Sound class #import'ed). Then in -viewDidLoad: mySound = [[Sound alloc] initWithPath:@"pathtoSound"]; and release it in -dealloc – Kurbz Jul 23 '10 at 15:45
  • Wow. That's how I did it... and I still get "fully working code" but "build and analyze" still reporting "possible leak". I tried it with (and with) @property/@synthesis statements. Same problem. – Annette Jul 23 '10 at 21:04
  • Leaking: mySound = [[Sound alloc] initWithPath:@"pathtoSound"]; (The code compiles and runs fine... so I know "most" of it is working.) But somewhere I must have a VERY small error in my code. But where? – Annette Jul 23 '10 at 23:43