2012-01-24 6 views
0

NSOperation (사용자가 버튼을 누를 때)을 취소하면 cancel 메소드가 주 스레드에서 호출되지만 분명히 작업이 다른 스레드에서 실행 중입니다. 그래서 _isExecuting 및 _isFinished를 변경할 때 경쟁 조건을 피하기 위해 취소 (또는 최소한 논리)는 NSOperation과 동일한 스레드에서 호출해야한다고 생각합니다. 그 외에도 사용자가 파일을 취소하면 여러 파일이 삭제되고 시간이 오래 걸립니다. cancel은 주 스레드에서 호출되기 때문에 잠시 동안 모든 앱이 응답하지 않아 추한 것입니다.작업과 동일한 스레드에서 NSOperation을 취소하려면 어떻게해야합니까?

어떻게 현재 NSOperation과 동일한 스레드에서 취소 코드를 실행할 수 있습니까?

나는 (내가 ASIHTTPRequest에서 본 것과 비슷한) 다음에 취소 시도 :

if (_operationThread) { 
    [self performSelector:@selector(cancelOnRequestThread) onThread:_operationThread withObject:nil waitUntilDone:NO]; 
} else { 
    [self cancelOnRequestThread]; 
} 

을 그리고 _operationThread 사용 시작 방법에 잘 살고있다 : _operationThread = [NSThread currentThread]

하지만 작동하지 않습니다.

의견이나 제안이 있으십니까?

참고 : 동시 작업을 사용하므로 main 대신 start를 사용합니다.

도움을 주셔서 감사합니다. 리카르도.

답변

4

메인 스레드의 NSOperation에서 취소를 호출해도됩니다. cancel 메소드는 스레드로부터 안전합니다.

취소 방법 자체가 어떤 일을해서는 안되기 때문에 주 스레드에서 차단을 일으켜서는 안됩니다. 파일, 기타 등등을 삭제하는 작업의 cancel 메소드를 재정의 한 경우 잘못된 접근입니다. cancel 메소드를 오버라이드해서는 안되며, 대신에 isCancelled 메소드를 작업의 메인 메소드 (예 : 긴밀한 루프 내부)의 정규 지점에서 확인한 다음 isCancelled가 YES를 반환하면 main에서 초기로 돌아가서 동일한 작업을 취소합니다 스레드를 실행 나머지로 간주합니다.

아직 구현 한 방법과 성능 문제가 계속되는 경우 작업이 실제로 백그라운드 스레드에서 실행되지 않을 수 있습니까? 예를 들어 [NSOperationQueue mainQueue]에 의해 반환 된 대기열에 추가했다면 실제로는 메인 애플리케이션 스레드에서 실행 중입니다.

관련 문제