核心动画+核心音频+睡眠不按预期顺序发生

时间:2012-05-29 04:44:55

标签: objective-c audio asynchronous core-animation

以下是我正在使用的一些代码。

我想要/期望的是什么:

  • 图片淡入;声音播放;延迟;图像淡出。

会发生什么

  • 延迟,声音播放,图像淡入,然后在
  • 之后立即淡出

任何帮助都非常感激。

ViewController.m

[self fadein];
NSString *tempFN;
SystemSoundID soundID;
tempFN = [[NSString alloc] initWithFormat:@"%@.caf", 
          [myGlobals.gTitleArray objectAtIndex:myGlobals.gQuoteCountForLoop]];
NSString *soundFilePath = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], tempFN];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
                         sizeof (sessionCategory),
                         &sessionCategory); 
AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundFileURL, &soundID);
AudioServicesPlaySystemSound(soundID);

// Now fade-out the image after a few seconds delay
sleep(3);
[self fadeout];

-(IBAction)fadein
{
    [UIImageView beginAnimations:NULL context:nil];
    [UIImageView setAnimationDuration:2];
    [faceImage setAlpha:0.3];
    [UIImageView commitAnimations];
}

-(IBAction)fadeout
{
    [UIImageView beginAnimations:NULL context:nil];
    [UIImageView setAnimationDuration:1];
    [faceImage setAlpha:0];
    [UIImageView commitAnimations];
}

2 个答案:

答案 0 :(得分:1)

我认为问题出在你使用“sleep(5)”时。使用sleep()函数会阻塞主线程,因此在该时间段内无法执行任何操作。在Objective-C中使用sleep()函数是非常罕见的,除非在某些命令行实用程序中。 我建议您使用NSTimer而不是sleep()函数。

希望这有帮助。

//编辑 另外,如果你真的必须使用sleep(),你应该使用NSThread类的sleepForTimeInterval:函数,并让其余的代码在辅助线程上运行。再一次,我真的不认为你应该使用sleep()函数或任何相关的函数。

答案 1 :(得分:0)

正如另一张海报所说,睡眠是个问题。睡眠冻结主线程。忘记睡眠存在。永远不要使用它。只有当你希望该线程停止运行一段时间,然后才真正知道你在做什么并发(一个非常高级的主题)时,唯一一次睡眠是有效的是在辅助线程上。

你应该做的是重写动画代码以使用animateWithDuration:动画:完成:

提供一个完成块,使用对animateWithDuration的嵌套调用来调用下一个动画:动画:完成:

每个动画将运行到最后,然后调用下一个动画。

顺便说一句,你应该看看AVAudioPlayer。它比AudioServices更强大,更易于使用。您只需创建一个AVAudioPlayer并告诉它播放。

如果你想让动画中的一个步骤等待声音竞争,AVAudioPlayer会接受一个声音完成播放后会调用的委托。

以下是我建议您重新制作动画序列的方法:

在开始动画序列之前,设置AVAudioPlayer并使视图控制器成为委托。

写一个animateWithDuration:动画:完成调用,动画块可以淡入。

在完成块中,启动AVAudioPlayer播放。

在AVAudioPlayer委托方法audioPlayerDidFinishPlaying:successfully:中,调用另一个animateWithDuration:animations:completion:方法再次淡出你的视图。