Как заставить один метод выполняться перед другим методом? - PullRequest
0 голосов
/ 27 марта 2010

У меня есть 2 метода. Один метод начинает воспроизведение аудиофайла (.mp3), другой метод обновляет UIToolBar для отображения кнопки (PLAY или PAUSE).Эти два метода вызываются в следующем порядке:

//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 ]

2 голосов
/ 27 марта 2010

Для обновления графического интерфейса вам необходимо дать ему возможность фактически обновить графический интерфейс.Поскольку воспроизведение звука происходит в другом потоке, оно начнет воспроизводиться сразу же.Однако, поскольку вы, вероятно, находитесь в событии из графического интерфейса (скажем, как событие касания), и вы еще не вернулись из этой функции, код, отвечающий за обновление графического интерфейса, еще не запущен.

См. http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ApplicationEnvironment/ApplicationEnvironment.html#//apple_ref/doc/uid/TP40007072-CH7-SW2 для получения информации о Cocoa Framework

Использование этой функции для вызова 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 голос
/ 18 ноября 2010

Другим подходом может быть подготовка системы к воспроизведению вашего аудиофайла, используя

[audioPlayer prepareToPlay];

где-то в вашем коде инициализации, например в viewDidLoad. Таким образом, все будет установлено, как только вы захотите воспроизвести звук, а метод play не вызовет значительной задержки. (не в коде вашего пользовательского интерфейса и не в реальном воспроизведении)

...