Запуск NSTimer в потоке NSOperationQueue

#ios #nstimer #nsoperationqueue

#iOS #nstimer #nsoperationqueue

Вопрос:

Я пытаюсь запустить NSTimer в потоке, настроенном NSOperationQueue

 -(void)apiCallbackQueueManager:(NSString *)callid :(NSString *)service:(NSString *)action:(NSString *)data{

SEL theSelector = @selector(apiCallbackQueueTimer: service: action: data:);
NSMethodSignature * sig = [self methodSignatureForSelector:theSelector];
NSInvocation * theInvocation = [NSInvocation invocationWithMethodSignature:sig];
[theInvocation setTarget: self];
[theInvocation setSelector: theSelector];
[theInvocation setArgument: amp;callid atIndex: 2];
[theInvocation setArgument: amp;service atIndex: 3];
[theInvocation setArgument: amp;action atIndex: 4];
[theInvocation setArgument: amp;data atIndex: 5];

NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithInvocation:theInvocation];
NSOperationQueue *apiQueue = [[NSOperationQueue alloc] init];
[apiQueue addOperation:operation];
 }

-(void)apiCallbackQueueTimer:(NSString *)arg1 service:(NSString *)arg2 action:(NSString *)arg3 data:(NSString *)arg4{
apiTimer =  [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(apiCallbackMonitor:) userInfo:[NSDictionary dictionaryWithObjectsAndKeys:arg1, @"callid", arg2, @"service", arg3, @"action", arg4, @"data", nil] repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:apiTimer forMode:NSDefaultRunLoopMode];
 }

-(void)apiCallbackMonitor:(NSTimer *)theTimer{
//do something
 }
  

Настройка вызова и запуск NSOperationQueue, похоже, в порядке, и метод apiCallbackQueueTimer вызывается с правильными аргументами. Проблема в том, что я не могу запустить NSTimer и поэтому перейти к моему методу apiCallbackMonitor.

Я читал в документах, что NSTimer требует цикла выполнения, поэтому я пытался его добавить.

Кто-нибудь может увидеть, что я делаю не так?

Ответ №1:

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

Изменение последних нескольких строк apiCallbackQueueTimer решило проблему.

  NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:apiTimer forMode:NSRunLoopCommonModes];
[runLoop run];
  

Ответ №2:

При создании этой операции NSInvocationOperation не создается экземпляр цикла выполнения. Вероятно, это происходит при запуске операции.

Тааак, я бы предложил подклассифицировать NSInvocationOperation и вызвать этот селектор apiCallbackQueueTimer при вызове вашего подкласса [NSInvocationOperation start] метод.

Комментарии:

1. apiCallbackQueueTimer должен выполняться в потоке, настроенном NSOperationQueue. Если я запущу таймер при вызове [NSInvocationOperation start], этот поток не будет создан, не так ли?

2. Я считаю, что это покрывается вашей [NSRunLoop currentRunLoop] вещью.