如何在另一个方法之前强制执行一个方法?

时间:2010-03-27 11:08:17

标签: iphone xcode avaudioplayer uibarbuttonitem uitoolbar

我有两种方法。 一种方法开始播放音频文件(.mp3),另一种方法更新UIToolBar以显示按钮(播放或暂停)。这两种方法按以下顺序调用:

//Adds some UIBarButtonItems to a UIToolBar
[self togglePlayer];
//Uses AVAudioPlayer
[audioPlayer play];

TogglePlayer执行此操作:

-(void)togglePlayer
{

    NSLog(@"Toggling Player");

    NSArray *barButtonItems;
    UIBarButtonItem *barButtonSpaceL;
    UIBarButtonItem *barButtonSpaceR;
    UIBarButtonItem *barButtonItemPlayer;
    UIBarButtonItem *barButtonItemCancel;
    UIBarButtonItem *barButtonItemLyrics;
    UIBarButtonItem *barButtonItemTweet;

    if([myToolbar.items count] > 0){

        NSEnumerator *enumerator = [myToolbar.items objectEnumerator];
        id object;
        while ((object = [enumerator nextObject])) {

            [object release];
            object = nil;
        }   
    }

    if(!downloadInProgress){

    barButtonSpaceL = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    barButtonSpaceR = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];

    if(thePlayerState == PLAYER_PLAYING){
    barButtonItemPlayer = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"pauseIcon.png"] style:UIBarButtonItemStylePlain target:self action:@selector(pauseButtonPressed:)];
    barButtonItemLyrics = [[UIBarButtonItem alloc] initWithTitle:@"Lyrics" style:UIBarButtonItemStyleBordered target:self action:@selector(switchPageLyrics:)];
    barButtonItemTweet = [[UIBarButtonItem alloc] initWithTitle:@"Tweet This" style:UIBarButtonItemStyleBordered target:self action:@selector(tweetSong:)];

        if(canTweet){
        barButtonItems = [NSArray arrayWithObjects:barButtonItemTweet, barButtonSpaceR, barButtonItemPlayer, barButtonSpaceL, barButtonItemLyrics, nil];
        }else{
        barButtonItems = [NSArray arrayWithObjects:barButtonItemPlayer, barButtonSpaceR, barButtonItemLyrics, nil];         
        }

    }else if(thePlayerState == PLAYER_PAUSED){

    barButtonItemPlayer = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"playIcon.png"] style:UIBarButtonItemStylePlain target:self action:@selector(playButtonPressed:)];
    barButtonItemLyrics = [[UIBarButtonItem alloc] initWithTitle:@"Lyrics" style:UIBarButtonItemStyleBordered target:self action:@selector(switchPageLyrics:)];
    barButtonItemTweet = [[UIBarButtonItem alloc] initWithTitle:@"Tweet This" style:UIBarButtonItemStyleBordered target:self action:@selector(tweetSong:)];


        if(canTweet){
            barButtonItems = [NSArray arrayWithObjects:barButtonItemTweet, barButtonSpaceR, barButtonItemPlayer, barButtonSpaceL, barButtonItemLyrics, nil];
        }else{
            barButtonItems = [NSArray arrayWithObjects:barButtonItemPlayer, barButtonSpaceR, barButtonItemLyrics, nil];         
        }   

    }else{

    //PLAYER OFF    
    barButtonItems = [NSArray arrayWithObjects:barButtonSpaceL, nil];

    }
        [myToolbar setItems:barButtonItems];    

    }else{


        barButtonSpaceL = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
        barButtonSpaceR = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
        barButtonItemCancel = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"VC1_DownloadCancel", @"") style:UIBarButtonItemStyleBordered target:self action:@selector(downloadCancelled:)];        

        if(thePlayerState == PLAYER_PLAYING){
            barButtonItemPlayer = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"pauseIcon.png"] style:UIBarButtonItemStylePlain target:self action:@selector(pauseButtonPressed:)];
            barButtonItems = [NSArray arrayWithObjects:barButtonItemPlayer, barButtonSpaceR, barButtonItemCancel, nil]; 

        }else if(thePlayerState == PLAYER_PAUSED){
            barButtonItemPlayer = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"playIcon.png"] style:UIBarButtonItemStylePlain target:self action:@selector(playButtonPressed:)];
            barButtonItems = [NSArray arrayWithObjects:barButtonItemPlayer, barButtonSpaceR, barButtonItemCancel, nil]; 

        }else{

        //PLAYER OFF
            barButtonItems = [NSArray arrayWithObjects:barButtonSpaceL, barButtonItemCancel, barButtonSpaceR, nil]; 
        }

        [myToolbar setItems:barButtonItems];


    }

}

我按上述顺序调用方法,以便在歌曲开始播放时显示(暂停)按钮。但是,问题是歌曲首先开始播放,并且UIToolBar在相当长的一段时间内(从2到5秒)保持不变,直到添加和显示按钮。

我想要的是在歌曲开始播放的同时显示按钮(即无延迟)。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:2)

为了更新gui,你需要给它一个实际更新gui的机会。由于音频播放发生在不同的线程中,它将立即开始播放。但是,由于你可能是gui的事件(比如触摸事件)并且你没有从该函数返回,负责更新gui的代码还没有运行。

有关Cocoa框架的信息,请参阅http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ApplicationEnvironment/ApplicationEnvironment.html#//apple_ref/doc/uid/TP40007072-CH7-SW2

使用此功能调用播放应该按照您想要的方式工作。这将使事件在处理当前事件后调用play。

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

你的例子:

//Adds some UIBarButtonItems to a UIToolBar
[self togglePlayer];
//Uses AVAudioPlayer
[audioPlayer performSelector:@SEL(play) withObject:nil afterDelay:0];

答案 1 :(得分:1)

另一种方法是使用

准备系统播放音频文件
[audioPlayer prepareToPlay];

初始化代码中的某处,例如在viewDidLoad。这样,一旦您想要播放音频,一切都将被设置,play方法不会导致显着的延迟。 (不在您的用户界面代码中,而不是在实际播放中)