2

I have a need to play a brief sound 3 seconds or so (like a count down beep) before I perform some other action in an iOS application.

The use case is as follows:

User clicks a button... the beeps play (simple beeps using AudioServicesPlaySystemSound... then the rest of the method is run.

I cannot seem to find out a way to block my method while the tones are playing.

I've tried the following:

[self performSelector:@selector(playConfirmationBeep) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];

But the tones play synchronously while the rest of the method is performed.

What am I missing with the above call?

4

1 回答 1

2

AudioServicesPlaySystemSound是异步的,所以你不能阻止它。您要做的是让音频服务在播放完成时通知您。您可以通过AudioServicesAddSystemSoundCompletion.

这是一个 C 级 API,所以事情有点难看,但你可能想要这样的东西:

// somewhere, a C function like...
void audioServicesSystemSoundCompleted(SystemSoundID ssID, void *clientData)
{
    [(MyClass *)clientData systemSoundCompleted:ssID];
}

// meanwhile, in your class' init, probably...
AudioServicesAddSystemSoundCompletion(
   soundIDAsYoullPassToAudioServicesPlaySystemSound,
   NULL, // i.e. [NSRunloop mainRunLoop]
   NULL, // i.e. NSDefaultRunLoopMode
   audioServicesSystemSoundCompleted,
   self);

// in your dealloc, to avoid a dangling pointer:
AudioServicesRemoveSystemSoundCompletion(
             soundIDAsYoullPassToAudioServicesPlaySystemSound);

// somewhere in your class:
- (void)systemSoundCompleted:(SystemSoundID)sound
{
    if(sound == soundIDAsYoullPassToAudioServicesPlaySystemSound)
    {
        NSLog(@"time to do the next thing!");
    }
}

如果您确实想在播放声音时阻止 UI,并假设您的类是视图控制器,您可能应该self.view.userInteractionDisable在相关期间禁用。你绝对不想做的是阻塞主运行循环;这将阻止重要的系统事件,例如低内存警告,从而可能导致您的应用程序被强制退出。您可能还想遵守诸如设备旋转之类的事情。

于 2012-08-15T23:20:50.597 回答