Как можно обновить элементы пользовательского интерфейса в iOS из цикла без потоков? - PullRequest
4 голосов
/ 12 июня 2011

Я хочу обновить метку из цикла, например, так:

- (void)viewDidLoad {
    [super viewDidLoad];
    int i=0; 
    while (1) {
         i++;
         [NSThread sleepForTimeInterval:0.05];  // do some computation,
         [myLabel setText:[NSString stringWithFormat:@"%d", i]]; // show the result!
         [self.view setNeedsDisplay];
    }

  }

Предположим, что вместо сна выполняются тяжелые вычисления.Я не хочу накладных расходов на выполнение вычислений в фоновом режиме.Эквивалентом Windows для решения этой проблемы будет .DoEvents, как показано в этом примере: http://www.tek -tips.com / viewthread.cfm? Qid = 1305106 & page = 1

Есть ли подобноерешение для этого в iOS?

[self.view setNeedsDisplay] не работает вообще!

Должен быть какой-то способ обработки событий приложения из iOS по контролируемому расписанию в главном потоке... Как и .DoEvents в Windows, несмотря на все его недостатки, весьма полезно для некоторых простых приложений.

Я думаю, это похоже на игровой цикл, но с компонентами пользовательского интерфейса.

Ответы [ 4 ]

3 голосов
/ 25 апреля 2012

Это можно сделать следующим образом:

-(void) incrementCounter:(NSNumber *)i {             
    [myLabel setText:[NSString stringWithFormat:@"%d", [i intValue]]]; // show the result!
    [self performSelector:@selector(incrementCounter:) withObject:[NSNumber numberWithInt:i.intValue+1] afterDelay:0.05];    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // start the loop
    [self incrementCounter:[NSNumber numberWithInt:0]];
}

Основная идея заключается в том, чтобы увеличить счетчик после небольшой задержки 0,05, чтобы дать основному потоку пользовательского интерфейса возможность сбрасывать все события пользовательского интерфейса,который компенсирует явный вызов .DoEvents в мире Windows.

1 голос
/ 12 июня 2011

Используйте NSTimer в iOS, если вы хотите обновить компоненты пользовательского интерфейса.

NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval: 60.0 target: self
                                   selector: @selector(callAfterSomeSecond:) userInfo: nil repeats: YES];

Реализация callAfterSomeSecond: как показано ниже:

-(void) callAfterSomeSecond:(NSTimer*) timer 
{
   static int counter = 0;

   if(counter == 100)
   {
      [timer invalidate];
   }
   [myLabel setText:[NSString stringWithFormat:@"%d", counter ]];
   [self.view layoutSubviews];
   counter++;
}
1 голос
/ 12 июня 2011

Я полагаю, вы хотите реализовать счетчик, используя метку? Вы можете использовать NSTimer для вызова метода, который обновляет ваш счетчик, например, каждые X миллисекунд.

0 голосов
/ 14 октября 2011

в вашем коде цикл while выполняется в главном потоке, и обновление пользовательского интерфейса также должно выполняться в главном потоке, поэтому во время выполнения цикла основной поток является «заблокированным» (занятым), поэтому обновление не может быть выполнено.

Я думаю, что я хочу сказать не то, что вы хотите. чтобы решить эту проблему, вы должны поместить тяжелые вычисления в другой поток, например, используя NSOperation или GCD.

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