2012-08-22 6 views
1

나는 객관적으로 다소 새로운 것 같습니다. 따라서 질문이나 코드가 이상하게 보일 경우 그 이유를 설명 할 수 있습니다. 나는 0.033 초마다 해고되는 NSTimer를 가지고있다.NSTimer - 논 블로킹 콜백

timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(timerCallback) userInfo:nil repeats:YES]; 

선택기 기능은 다음과 같습니다

BOOL running = false; 
- (void) timerCallback 
{ 
    if (running) { 
    return; 
    } 
    running = true; 
    //Do some stuff 
    running = false; 
} 

것입니다, 기능 timerCallback 상관없이 동기화를 유지하기 위해 무엇을이 간격으로 해고되어야한다. (세부 사항으로 건너 뛰는)

but ... 그것이 나왔던 것에 따라, timerCallback 기능은 NSTimer를 멈추게하고, 그것이 재개하기 전에 완료 할 것을 기다리게한다?

간격을 유지하려면 어떤 옵션이 필요합니까? timerCallback 함수가 별도의 스레드에서 실행될 수 있습니까? NSTimer보다 더 나은 옵션이 있습니까? 아마도 별도의 스레드로 시작할 것인가?

+0

타이머가 반복해서 호출되지 않는다는 의미입니까? –

+0

타이머 간격 내에서 'timerCallback' 작업을 수행 할 수 없다면 궁극적으로 문제가 발생할 "작업"백 로그를 생성하지 않습니까? – trojanfoe

+0

아니요. 즉, timerCallback에 0.1 초가 필요하면 NSTimer가 중지되고 함수가 완료 될 때까지 기다린 다음 다시 시작합니다. 결과적으로, 나는 느슨한 동기화. 항상 0.033 초 간격을 유지해야합니다. – GuruMeditation

답변

0

타이머는 NSTimer 및 NSRunLoop의 설계로 인해 정확한 타이밍을 제공 할 수 없기 때문에 시간에 따라 평균 된 원하는 점화 간격을 유지하려고 시도합니다. 그 타이머의 코드가 0.033 초를 넘으면 타이머가 한 통화를 건너 뛰는 지 아닌지 확실하지 않습니다.

이 실험을 시도하십시오 - 타이머를 설정 한 다음 모든 작업을 주석 처리하고 로그하십시오 시간. 원하는 시간과 매우 가깝습니다. 즉, 1 초에 30 회의 통화로 UI를 터치하는 경우 얻을 수있는 최대 성능에 가깝습니다.

변형의 양을 최소화하는 한 가지 전략은 블록 내에서 수행하는 모든 코드를 배치하고이를 주 큐에 전달하거나 더 나은 방법으로 병행 스레드에 디스패치하는 것입니다. 그렇게하면 매우 짧은 기간에 통화에서 복귀 할 수 있습니다.

만약 당신에게 맞는 것이 없다면, CADisplayLink를보십시오. 매우 높은 우선 순위에서 실행되므로이 ​​기능을 사용하여 매우 정확한 콜백을 얻을 수 있습니다. 그러나 콜백에서 중요한 것은 아무것도 할 수 없습니다. 그러나 메인 큐 (메인 스레드)에서 처리하기 위해 블록을 큐에 디스패치 할 수 있습니다.

+0

dispatch_queue_t가 구현되어 현재 문제를 해결 한 것으로 보인다. 나중에 가장 비싼 방법이 무엇인지 확인해야합니다. – GuruMeditation

2

차단을 방지하기 위해 다음과 같이 사용하는 것이 좋습니다.

BOOL running = false; 
- (void) timerCallback 
{ 
    if (running) { 
    return; 
    } 

    [(NSOperationQueue*)_myOperationQueue addOperationWithBlock:^{ 
    running = true; 
    //do Some Stuff 
    running = false 
    }]; 
} 
+0

dispatch_queue_t를 구현하여 현재이 문제를 해결 한 것으로 보입니다. 이 방법과 비교하여 어느 것이 가장 비싸지 않은지 확인합니다. – GuruMeditation

+0

이 코드에서는 블록이 동시에 실행되므로 __block OSAtomic (man 3 atomic 참조) 플래그를 사용하여 "running"플래그를 설정하고 지우고 싶습니다. 실행중인 것은 NSTimer가 콜백을 "스택"하지 않는다고 생각하기 때문에 원본 코드에서 빨간색 청어의 일종입니다. –

관련 문제