Question

I have a thing that uses a SystemSoundID to play a sound, and then repeat with a C function being used as the sound completion callback, and the function is passed (void *)self (since it has to be a void pointer), and then I want to play the sound again if the alarmPlaying BOOL ivar of self is true, otherwise remove the sound completion and dispose the SSID (providing an instance method to set alarmPlaying to NO). What it the proper way to take self in the form of a void pointer and get its alarmPlaying ivar? There's no point in using a property if I don't need to. I keep getting the error Request for member 'alarmPlaying' in something not a structure or union, and a dereferencing void pointer warning. Here's the function I have:

static void alarmSoundDidComplete(SystemSoundID soundID, void *myself) {
    // ******* How do I access alarmPlaying from a 'self' casted to a void * ? *******
    if((MidnightViewController *)myself->alarmPlaying) {
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        [NSThread sleepForTimeInterval:kAlarmBeepInterval];
        AudioServicesPlaySystemSound(soundID);
    } else {
        AudioServicesRemoveSystemSoundCompletion(soundID);
        AudioServicesDisposeSystemSoundID(soundID);
    }
}

(Its running on its own thread, so I have a kAlarmBeepInterval #define'd)

and in the implementation of the class I have:

- (void)startPlayingAlarm {
    SystemSoundID alarmSoundID = [Utilities createSystemSoundIDFromFile:@"beep"
                                                                 ofType:@"caf"];
    AudioServicesAddSystemSoundCompletion(alarmSoundID, NULL, NULL,
                                          alarmSoundDidComplete, (void *)self);
    alarmPlaying = YES;
    AudioServicesPlaySystemSound(alarmSoundID);
}

- (void)stopPlayingAlarmAndDisposeSystemSoundID {
    alarmPlaying = NO;
}

Thanks.

Was it helpful?

Solution

-> has higher precedence than the cast; you need to do this:

if(((MidnightViewController *)myself)->alarmPlaying) {

OTHER TIPS

I believe the proper way would be to create a property (sorry), because encapsulation is the object oriented way. To not get the error and do what you're trying to do you need to make the ivar public using @public in the interface. By default, all ivars are protected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top