Почему NSTimer блокируется во время работы другого потока? - PullRequest
3 голосов
/ 11 марта 2011

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

- (void)viewDidLoad
{
    [super viewDidLoad];

    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self
                   selector:@selector(onTimerEvent:)
                   userInfo:nil repeats:YES];   

   [self performSelectorInBackground:@selector(lengthyMethod) withObject:nil];

    NSLog(@"Here we go!");
}

- (void)onTimerEvent:(NSTimer *)timer
{
    NSLog(@"timer!");
}

lenghtyMethod выполняет множество задач, включая загрузку URL-адресов с использованием ASIHTTPRequest и т. Д.

Вывод NSLog выглядит следующим образом:

2011-03-11 15:17:07.470 MyApp[6613:207] Here we go!    
2011-03-11 15:17:07.570 MyApp[6613:207] timer!
2011-03-11 15:17:07.670 MyApp[6613:207] timer!

// ... several seconds of output from lenghtyMethod omitted ...

2011-03-11 15:17:11.075 MyApp[6613:207] timer!
2011-03-11 15:17:11.170 MyApp[6613:207] timer!
// ... etc ... timer runs as expected when the call is completed ...

Проблема в том, что фоновый поток, кажется, блокирует таймер . Насколько я понимаю, executeSelectorInBackground должен выполняться в новом потоке, отдельном от основного цикла.

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

Что касается записи, поток в основном выполняет операции ввода-вывода (загрузки URL-адресов), поэтому у ОС должно быть достаточно времени для переключения потоков. Это происходит как в симуляторе, так и на реальном устройстве.

Ответы [ 2 ]

6 голосов
/ 12 марта 2011

Согласно ASIHTTPRequest :

Для более сложных ситуаций или в тех случаях, когда вы хотите проанализировать ответ в фоновом режиме, создайте минимальный подкласс ASIHTTPRequest для каждого типа запросаи переопределите requestFinished: и failWithProblem:.

В противном случае, если вы используете обратные вызовы по умолчанию, они будут выполняться в главном потоке.

1 голос
/ 11 марта 2011

NSTimer работает в том же потоке.
Вызывает метод события в главном потоке.

Ваш метод lengthyMethod, вероятно, использует основной шаг для выполнения некоторых операций.
Перед этим основным блоком потока было 2 такта.
Проверьте это!

...