iPhone SDK - Запуск повторяющегося процесса в фоновом потоке - PullRequest
4 голосов
/ 30 марта 2012

У меня есть приложение iPhone, в котором я хочу выполнять метод в фоновом режиме каждую 1 секунду.

Итак, в моем главном потоке у меня есть следующий код на UIViewController viewDidLoad():

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

следующими методами:

-(void)repeatedMethod {
  if(!processIsRunning) {
    processIsRunning = YES;
    [self performSelectorInBackground:@selector(runProcessInBackground:) withObject:myImage];
  }
}

-(void)runProcessInBackground:(UIImage *)image {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  ... Some operations ...
  ...   also call a method on the main thread which sets isProcessRunning to NO

  [pool release]
}

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

Теперь мои вопросы:

(1) Это лучший способ сделать это?Или есть более подходящий способ сохранить и повторно использовать фоновый поток?

(2) Какой самый быстрый способ сделать это?Неужели я теряю время, раскручивая новые фоновые потоки при каждом вызове метода?

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

Любой совет будет отличным!Кто-нибудь имел дело с этим типом вопроса раньше?

Большое спасибо, Бретт

1 Ответ

13 голосов
/ 30 марта 2012

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

Примерно так:

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, backgroundQueue);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, 0), 1.0*NSEC_PER_SEC, 0*NSEC_PER_SEC);
dispatch_source_set_event_handler(timerSource, ^{
    [self repeatedMethod];
});
dispatch_resume(timerSource);

- (void)repeatedMethod {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self doStuffWithAnImage:self.myImage];   

    [pool drain];
}

Одна из самых крутых вещей в блоках заключается в том, что они охватывают локальную область видимости. На самом деле это не используется в моем примере выше, но делает «передачу» объектов в GCD тривиальной. Смотрите мой ответ на этот вопрос: Есть ли преимущество в использовании блоков над функциями в Objective-C? .

...