如何在该方法本身正在进行异步任务时跳过对方法的预定调用?
假设我有做一些异步任务的方法。假设它刷新用户的访问权限,并且可能需要几分钟时间,具体取决于互联网连接速度等。如何在该方法本身正在进行异步任务时跳过对方法的预定调用?
我不得不周期性地调用该方法(即,使用排定呼叫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秒触发一次。
我需要做的是,我需要以某种方式跳过一个(或多个) 计划调用此方法如果事情是, 异步块内部发生(比方说,用户的访问许可尚未 更新)。
但是一旦块完成(也就是说,用户的访问权限已更新),与计时器排定呼叫应该恢复。
任何想法或如何做到这一点的任何样本?
我想出这个办法。 @ 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
的值。因此,在更改共享变量的值时,最好使它保存为线程。
我想你可以通过使用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;
}
}
}
嗯,这是聪明的。但是,我认为应该在'dispatch_async'块之前检查并设置bool为YES。对? – nayem
但是它保证**在dispatch_async块内设置'isExecuting = NO'会在任务完成后发生**吗? – nayem
更新的答案应该可以工作。 – Sunny