Цель C - получить доступ к BOOL ivar из void, указывающего на себя - PullRequest
0 голосов
/ 01 октября 2009

У меня есть вещь, которая использует SystemSoundID для воспроизведения звука, а затем повторяется с функцией C, используемой в качестве обратного вызова для завершения звука, и функция передается (void *)self (поскольку это должен быть указатель void), и затем я хочу воспроизвести звук снова, если значение alarmPlaying BOOL ivar of self равно true, в противном случае удалите завершение звука и избавьтесь от SSID (предоставив метод экземпляра для установки alarmPlaying на NO). Как правильно взять self в виде пустого указателя и получить его тревогу, проигрывая ivar? Нет смысла использовать свойство, если мне это не нужно. Я получаю сообщение об ошибке Request for member 'alarmPlaying' in something not a structure or union и предупреждение о разыменовываемом указателе пустоты. Вот функция, которую я имею:

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);
    }
}

(работает в собственном потоке, поэтому у меня есть kAlarmBeepInterval # define'd)

и в реализации у меня есть:

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

- (void)stopPlayingAlarmAndDisposeSystemSoundID {
    alarmPlaying = NO;
}

Спасибо.

Ответы [ 2 ]

1 голос
/ 01 октября 2009

Я считаю, что правильным способом было бы создать свойство (извините), потому что инкапсуляция - это объектно-ориентированный способ. Чтобы не получить ошибку и сделать то, что вы пытаетесь сделать, вам нужно сделать ivar общедоступным, используя @public в интерфейсе. По умолчанию все ивары защищены.

1 голос
/ 01 октября 2009

-> имеет более высокий приоритет, чем приведение; вам нужно сделать это:

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