Как я могу заставить метод останавливаться на фиксированное количество времени? - PullRequest
4 голосов
/ 25 мая 2011

У меня есть приложение, которое вызывает иногда быстрый, иногда медленный метод. Я знаю верхнюю границу, сколько времени это займет (2 секунды). Я хотел бы установить таймер для запуска при вызове метода, запустить код, но затем не выводить результат, пока не пройдет 2 секунды, независимо от того, сколько времени это на самом деле занимает. Таким образом, пользователь воспринимает действие как всегда занимающее одинаковое количество времени. Как я могу это реализовать?

Что бы я хотел, это что-то вроде этого:

-(IBAction)doStuff {

  // START A TIMER, LOOK BUSY
  [activityIndicator startAnimating];

  ... real work happens here ...
  ... NSString *coolString gets assigned ...

  // WHEN TIMER == 2 SECONDS, REVEAL COOLNESS
  [activityIndicator stopAnimating];
  [textField setText:coolString];

}

Ответы [ 3 ]

6 голосов
/ 25 мая 2011

Есть несколько способов отложить действие в Какао. Самым простым может быть использование performSelector:withObject:afterDelay:. Этот метод устанавливает для вас таймер и вызывает указанный метод, когда придет время. Это метод NSObject, поэтому все ваши объекты получают его бесплатно.

Сложность в том, что первый метод блокирует основной поток, поэтому вам нужно перевести его в фоновый поток, а затем вернуться в основной поток, чтобы обновить пользовательский интерфейс. Вот удар в этом:

// Put the method which will take a while onto another thread
[self performSelectorInBackground:@selector(doWorkForUnknownTime)
                       withObject:nil];
// Delay the display for exactly two seconds, on the main thread
[self performSelector:@selector(displayResults)
           withObject:nil
           afterDelay:2.0];

- (void)doWorkForUnknownTime {

   // results is an ivar
   results = ...; // Perform calculations
}

- (void)displayResults {
    if( !results ){
        // Make sure that we really got results
        [self performSelector:@selector(displayResults:)
                   withObject:nil
                   afterDelay:0.5];
        return;
    }

    // Do the display!
}

Единственное, о чем я могу думать, - это сохранить время, когда метод "work" вызывается в NSDate, и проверить, сколько времени прошло, когда вы получите результаты. Если это еще не две секунды, переведите фоновый поток в спящий режим, а затем перезвоните основному потоку, когда закончите.

[self performSelectorInBackground:@selector(doWorkForUnknownTime:)
                       withObject:[NSDate date]];

- (void)doWorkForUnknownTime:(NSDate *)startTime {

   // All threads must have an autorelease pool in place for Cocoa.
   @autoreleasepool{
       // This will take some time
       NSString * results = ...; // Perform calculations

       NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startTime];
       if( elapsedTime < 2.0 ){
           // Okay to do this to wait since we're on a background thread, 
           // although not ideal; sleeping threads are kind of wasteful.
           // Try not to do this a lot.
           sleep(2.0 - elapsedTime);
       }

       // Don't forget to retain results on the main thread!
       [self performSelectorOnMainThread:@selector(displayResults:)
                              withObject:results
                           waitUntilDone:YES];
//     [results release];    // if necessary
    }
}
0 голосов
/ 25 мая 2011
-(IBAction)doStuff {

  // START A TIMER, LOOK BUSY
  [activityIndicator startAnimating];

  ... real work happens here ...
  ... NSString *coolString gets assigned ...

  // WHEN TIMER == 2 SECONDS, REVEAL COOLNESS
[self performSelector:@selector(revealCoolnessWithString:) withObject:coolString afterDelay:2];

}

- (void)revealCoolnessWithString:(NSString *)coolString
{
[activityIndicator stopAnimating];
[textField setText:coolString];
}

Надеюсь, это поможет

0 голосов
/ 25 мая 2011
[self performSelector:@selector(myfunc) withObject: afterDelay:];  

должно помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...