2014-12-16 6 views
3

5 초 동안 트리거 된 타이머가 글로벌 대기열에 추가되었지만 2 초 후에 무효화되지만 실행 루프는 5 초까지 종료되지 않습니다. 다음 스 니펫에서 backgroundTimer는 인스턴스 var이고 run은 멤버 함수입니다. 실행 루프 종료를 차단하는 다음 코드에서 무엇이 잘못 되었습니까?즉시 runloop에서 타이머를 제거하는 방법

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    _backgroundTimer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(run) userInfo:nil repeats:NO]; 
    [ [NSRunLoop currentRunLoop] addTimer:_backgroundTimer forMode:NSRunLoopCommonModes]; 
    [[NSRunLoop currentRunLoop] run]; 

    NSLog(@"Run loop terminated"); 

}); 

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [_backgroundTimer invalidate]; 
    _backgroundTimer=nil; 

}); 
+0

심지어 CFRunLoopStop ([[NSRunLoop currentRunLoop] getCFRunLoop])을 추가하려고 시도했습니다. 무효화 후, – pradeepa

답변

3

첫 번째 문제는 타이머가 어떤 임의의 배경 스레드에서 실행 루프에 추가 될 것입니다. (즉, 백그라운드 큐를 서비스하기 위해 GCD에서 쓰레드를 생성 할 것입니다.) 일 수 있습니다.

수동으로 제거 알려진 모든 입력 소스 : 제쳐두고, 당신은 당신이 원하는 것을이 실행 루프는 종료입니다 발생하지만, -run 방법에 대한 설명서에 말했다

는, 다음을 말한다 실행 루프 의 타이머는 실행 루프가 종료된다는 것을 보장하지 않습니다. OS X는 을 설치하고 수신기의 스레드에서 을 대상으로하는 요청을 처리하는 데 필요한 추가 입력 소스를 제거 할 수 있습니다. 따라서 이러한 소스는 실행 루프가 종료되지 않도록 을 막을 수 있습니다.

실행 루프를 종료하려면이 방법을 사용하지 않아야합니다. 대신 다른 실행 방법 중 하나를 사용하고 다른 자신의 임의 조건을 루프에서 확인하십시오.

당신은 타이머가 무효 인 경우를 종료 할 경우이 이벤트 루프를 직접 회전해야합니다. 예를 들어 : (- 엡실론) 타이머가 무효화 초 후에

while (_backgroundTimer.valid && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow: 0.1]]); 

이 실행 루프를 0.1의 최대 종료됩니다.

0

다음과 같이하십시오 :

[NSRunLoop cancelPreviousPerformRequestsWithTarget:self selector:@selector(run) object:nil]; 

편집 : 여기

-(void)run{ 
    if(taskComplete){ 
     [_backgroundtimer invalidate]; 
} 
+0

그것이 작동하지 않았을 시도, 나는 cancelPreviousPerformRequestsWithTarget performSelector 방법 패밀리를 사용하여 예약 된 것들만 취소됩니다 생각합니다. – pradeepa

+0

실행을 호출하기 전에 runloop을 종료해야합니다. 메소드를 실행하기위한 첫 번째 반복 동안이 아니라 후속 반복 중에 실행해야합니다. – pradeepa

+0

@pradeepa 코드가 제대로 작동하는지 확인 했습니까? 실행 메소드 호출 전에 타이머를 종료합니다. – cyberlobe