2017-03-16 54 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

相關問題