2017-03-16 29 views
0

假设我有做一些异步任务的方法。假设它刷新用户的访问权限,并且可能需要几分钟时间,具体取决于互联网连接速度等。如何在该方法本身正在进行异步任务时跳过对方法的预定调用?

我不得不周期性地调用该方法(即,使用排定呼叫NSTimer的方法scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:

-(void)refreshPermission { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     // do something that takes a few minutes 
    }); 
} 

现在我调用此方法如timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(refreshPermission) userInfo:nil repeats:YES];。也就是说,这个调用每10秒触发一次。

我需要做的是,我需要以某种方式跳过一个(或多个) 计划调用此方法如果事情是, 异步块内部发生(比方说,用户的访问许可尚未 更新)。

但是一旦块完成(也就是说,用户的访问权限已更新),与计时器排定呼叫应该恢复。

任何想法或如何做到这一点的任何样本?

回答

0

我想出这个办法。 @ Sunny提供了这个想法。

它为我工作。但是,有关此实现的任何建议,我们感激。

-(void)refresh { 
    NSLog(@"Refresh called"); 
    NSLock *theLock = [[NSLock alloc] init]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     NSLog(@"Async task assigned"); 

     if(!isExecuting){ 

      [theLock lock]; 
      isExecuting = YES; 
      [theLock unlock]; 

      // Perform your tasks 
      NSLog(@"Async task started"); 
      [NSThread sleepForTimeInterval: 13.0]; // for testing purpose 
      NSLog(@"Async task completed"); 

      [theLock lock]; 
      isExecuting = NO; 
      [theLock unlock]; 

     } 
    }); 
} 

这里isExecuting是包含类的实例变量。在设置定期调用方法的实际计划定时器之前,它被设置为isExecuting = NO;

这里我使用NSLock来确保在线程执行任务时没有其他线程可以更改值isExecuting。我添加了这个锁,因为每次调用-(void)refresh方法时,都有可能多个线程有资格执行并更改isExecuting的值。因此,在更改共享变量的值时,最好使它保存为线程。

1

我想你可以通过使用Bool变量做到这一点。您可以全局声明Bool变量,并通过使用它的状态,你可以管理函数调用你的任务。

在方法refreshPermission

-(void)refreshPermission { 
    if(!isExecuting){ 

     isExecuting = YES; 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     // Perform your tasks 

     isExecuting = NO; 
     } 
    } 
} 
+0

嗯,这是聪明的。但是,我认为应该在'dispatch_async'块之前检查并设置bool为YES。对? – nayem

+0

但是它保证**在dispatch_async块内设置'isExecuting = NO'会在任务完成后发生**吗? – nayem

+0

更新的答案应该可以工作。 – Sunny