0

I have a method AudioServicesCreateSystemSoundID that according to the documentation seems to require a memory address passed in (*outSystemSoundID).

From Apple's Website...

OSStatus AudioServicesCreateSystemSoundID (
   CFURLRef       inFileURL,
   SystemSoundID  *outSystemSoundID
);

I have this code that works when I create a local object within the method. The object is assigned correctly to the memory location.

This returns myTest with code: 0 ( this is what I want )

 SystemSoundID thisSoundID;

 SystemSoundID myTest = AudioServicesCreateSystemSoundID
 (
 (__bridge CFURLRef)(url), &thisSoundID
 );

But this is what I am trying to do. (self.theSound I have set up as a SystemSoundID property).

This returns myTest with error code : 4294967246 ( I do not want this )

SystemSoundID myTest = AudioServicesCreateSystemSoundID
(
    (__bridge CFURLRef)(url), self.theSound
);

1 Answers1

1

The compiler translates self.theSound to

[self theSound]

where -(SystemSoundID)theSound is the (automatically synthesized) getter method of you property which (by default) gets the value from the _theSound instance variable.

So you cannot take the "address of a property" and pass it to a function. You could pass the address of the instance variable instead:

SystemSoundID myTest = AudioServicesCreateSystemSoundID
(
    (__bridge CFURLRef)(url), &self->_theSound
);

bypassing the property accessor. But I would recommend to use a temporary variable instead:

 SystemSoundID thisSoundID;
 SystemSoundID myTest = AudioServicesCreateSystemSoundID
 (
     (__bridge CFURLRef)(url), &thisSoundID
 );
 self.theSound = thisSoundID;
Martin R
  • 488,667
  • 78
  • 1,132
  • 1,248
  • Nice answer. Would you happen to know a reference to _"..you cannot take the "address of a property" and pass it to a function. You could pass the address of the instance variable instead.."_? I faintly remember reading that somewhere long time ago, but I don't recall where. I would like to brush up a little on that. Thanks in advance. – Unheilig Jan 27 '14 at 18:22
  • This works for the successful creation of the object. However it does not seem to persist outside of the function. IE. If I call the exact same method inside the function it works.... outside that function no work. `code AudioServicesPlaySystemSound(*(self.theSound)); // immediatley after works. However, the following does not.. - (void) playSound { NSLog(@"Called playSound"); AudioServicesPlaySystemSound(*(self.theSound)); } – Fanny Darmer Jan 27 '14 at 18:36
  • @FannyDarmer: Why `AudioServicesPlaySystemSound(*(self.theSound))` ? Shouldn't that be `AudioServicesPlaySystemSound(self.theSound)` ? – Martin R Jan 27 '14 at 18:53
  • I tried that - but get the error: "incompatible pointer to integer conversion..." – Fanny Darmer Jan 27 '14 at 19:06
  • @FannyDarmer: Could it be that you declared your property as `SystemSoundID *theSound` ? It should be `SystemSoundID theSound`. The sound ID is a simple integer, not a pointer. – Martin R Jan 27 '14 at 19:09
  • @Unheilig: It is nicely explained here: http://stackoverflow.com/a/7616429/1187415. Does that help? – Martin R Jan 27 '14 at 19:16
  • Yes, that did it. Thanks Martin! Now I can move on. =) Cheers! – Fanny Darmer Jan 27 '14 at 19:19
  • @MartinR Definitely. Thanks. So, in Fanny's case here, since `SystemSoundID` is really `uint32_t` (non-object), using `&self->theSound;` becomes necessary because of its non-object type? But this alone: `&theSound` wouldn't work? +1 in advance. – Unheilig Jan 27 '14 at 19:33
  • @Unheilig: It has nothing to do with object type or not. `self.theSound` is just a short notation for the *method call* `[self theSound]` which returns (in this case) an integer. But you cannot take the address of the return value of a function! (Technically, the return value of a function is not an "Lvalue".) - `self->theSound` is just an integer variable, so you can take its address. – Martin R Jan 27 '14 at 19:45
  • @MartinR Right, we are on the same page. All clear. Thanks again :-) – Unheilig Jan 27 '14 at 19:50