2017-03-16 1 views
0

일부 비동기 작업을 수행하는 메소드가 있다고 가정합니다. 사용자의 액세스 권한을 새로 고침하고 인터넷 연결 속도 등에 따라 몇 분이 걸릴 수도 있습니다.비동기 작업이 해당 메서드 자체에서 진행될 때 메서드에 대한 예약 된 호출을 건너 뛰는 방법은 무엇입니까?

제가

-(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];이 메소드를 호출 (즉 예정된 통화 scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:NSTimer의 방법을 사용하여) 정기적으로이 방법을 호출해야한다. 즉,이 호출은 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;으로 설정되었습니다.

스레드가 작업을 실행하는 동안 다른 스레드가 isExecuting의 값을 변경할 수 없다는 보장을 위해 여기에서 NSLock을 사용했습니다. -(void)refresh 메서드가 호출 될 때마다이 잠금이 추가되었으므로 복수 스레드가 실행 및 변경 값 isExecuting에 적합하게 될 가능성이 있습니다. 따라서 공유 변수의 값을 변경할 때 쓰레드를 저장하는 것이 좋습니다.

1

나는 변수를 사용하여이를 수행 할 수 있다고 생각합니다. 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

음, 그건 영리한거야. 하지만 bool을 YES로 체크하고 설정하는 것은'dispatch_async' 블록 전에 수행되어야한다고 생각합니다. 권리? – nayem

+0

그러나 작업 ** 완료 후'dispatch_async' 블록 내에'isExecuting = NO' 설정은 보장됩니까? – nayem

+0

업데이트 된 대답이 효과가 있습니다. – Sunny

관련 문제