2013-06-01 3 views
0

Я делаю инструмент CLI для Mac OS X, мои основные выглядят примерно так:NSTimer/NSRunLoop вопросы

int main(int argc, const char * argv[]){ 

    @autoreleasepool { 

     //Some startup stuff here 
     [ServerPool sharedPool]; //Start the pool 

     /* 
     UI stuff for cli version 
     */ 
     while (1){ 
      [[CLIUI sharedCLI] mainMenu]; 
      [[CLIUI sharedCLI] menuInput]; 
     } 

    } 
    return 0; 
} 

и в другом разделе кода я начинаю NSTimer

progressUpdateTimer = [NSTimer timerWithTimeInterval:1.0 
               target:self 
              selector:@selector(updateProgress:) 
              userInfo:nil 
              repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer: progressUpdateTimer forMode:NSDefaultRunLoopMode]; 

Однако он никогда не запускает селектор updateProgress :. Я считаю, что это связано с тем, что у меня нет основанного на моей базе NSRunLoop, что было бы правильным решением для этого?

+0

Блокируйте ли методы 'mainMenu' и' menuInput' до тех пор, пока не произойдет какое-либо событие? Или они просто проводят опрос на мероприятие и немедленно возвращаются? Если они блокируют, что они блокируют? –

+0

fgets (_input, sizeof _input, stdin); ... –

+0

Я бы хотел сделать главное меню и ввести фоновый поток, не так ли? –

ответ

1

Таймеры и все остальное, зависящее от цикла запуска, не срабатывает, если не запущен цикл выполнения.

В программе командной строки, вы бы идеально использовать dispatch_main() и передать управление НОДОМ или запуск [NSThread currentRunLoop] в соответствующем режиме в течение соответствующего периода времени.

Вам нужно избавиться от этого while(1), поскольку он заблокирует цикл запуска.

concurrent programming documentation содержит подробную документацию по использованию циклов запуска.

Если вам действительно нужен цикл while, переместите его во второй поток (с NSRunLoop в основном потоке намного легче справиться) и запустите цикл запуска в основном потоке.


Вам нужно заменить эту while(1) петлю с NSRunLoop. Который также, вероятно, означает, что вам нужно будет изменить код ввода как dispatch_source или NSFileHandle, который читается с stdin и т. Д.

I.e. вам придется немного реорганизовать свой код. Сделайте поиск в Google для чего-то вроде «использования nsrunloop в командной строке», и вы, вероятно, получите немало намеков. Кроме того, документация NSRunLoop указывает на кучу примеров.

Это может показаться сложной задачей, но как только вы получите NSRunLoops, это удивительно мощные конструкции.

+0

Не могли бы вы подробно остановиться здесь? Я полностью забываю, как (или где) мой основной цикл должен делать/уходить ... –

+0

Я переключился на это: https://gist.github.com/RyanCopley/829d33bb328651b1fb1b Все работает, кроме таймеры все еще не стреляют. –

+0

Что делает ваш метод sharedCLI? Если он блокируется, ожидая ввода, то таймеры не будут срабатывать (поэтому вы хотите перейти на NSFileHandle или переместить существующий ввод-вывод с основного потока). – bbum