0

그래서, 분명히 여기 뭔가 잘못하고 있습니다. MVC를 사용하는 응용 프로그램이 있고 모델 클래스 중 하나에서 처리하는 데 약간의 시간이 걸릴 수있는 웹 서비스 호출이 있습니다. 뷰 컨트롤러는 다운로드 프로세스를 시작하는 모델 클래스의 메서드를 호출합니다. 다운로드 프로세스는 NSOperationQueue에있는 AFHTTPRequestOperation을 통해 수행됩니다. 전체 다운로드 프로세스는 뷰 컨트롤러 외부의 모델 클래스에서 발생합니다. 그러나 작업 중에 UI가 응답하지 않으면 다운로드 작업이 주 스레드를 차단하는 것으로 나타납니다. 느린 네트워크를 시뮬레이트하기 위해 일시 ​​중지를 하드 코드했습니다. 작업이 완료되면 대리자 메서드를 통해보기 컨트롤러를 호출합니다. 이 코드는 작동하지만 앞에서 언급했듯이 주 스레드를 차단합니다. 내보기 컨트롤러에서NSoperationQueue 메인 스레드를 차단

-(void)getGaugeReadings{ 

    NSString *endpointURL = [NSString stringWithFormat:@"http://...", stationID_, timeSpan_]; 

    NSURL *url = [NSURL URLWithString:endpointURL]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){ 
     NSData *data = (NSData*)responseObject; 
     [self processXmlObject:data]; 
     [self setGaugeFlowKeys:[self getFlowKeys]]; 
     [NSThread sleepForTimeInterval:3]; 
     [self.delegate updateGaugeTable]; 
    }failure:^(AFHTTPRequestOperation *operation, NSError *err){ 
     NSLog(@"ERROR: %@", [err localizedDescription]); 
    }]; 

    NSOperationQueue *gaugeDownloadQueue = [[NSOperationQueue alloc] init]; 
    [gaugeDownloadQueue setName:@"Gauge_Download"]; 
    [gaugeDownloadQueue addOperation:operation]; 
} 

나는 (하드 매개 변수) 내있는 viewDidLoad에서 다음과 같은 한 :

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    gauge = [[StreamGauge alloc] initWithStationID:@"A3185AX400" forTimeSpan:24];   
    [gauge setDelegate:self]; 
    [gauge getGaugeReadings]; 
} 

나는 더 나는 내 모델 클래스 (StreamGauge)에서

나는 다음이 이런 것들에 대해 GCD를 사용하는 것에 익숙하지만, 이제는 타임 아웃이 만료 된 후에 작업을 취소 할 수있는 능력이 필요합니다. 따라서 NSOperationQueue가 더 적절하지만 분명히 작업 대기열에 대한 철저한 이해가 부족합니다.

이 백그라운드 작업을 모델 클래스에 배치하는 데 문제가있을 수 있습니까? 백그라운드 작업은 항상 컨트롤러 클래스에 있어야합니까? 다른 건 내가 여기서 잘못하고있는거야?

답변

1

문제는 gaugeDownloadQueue을 유지하지 않는 것입니다. 그래서 그것은 단지 연기가 나면서 사라지고 모든 것이 메인 스레드에서 발생합니다. (당신이 어떤 작업을 큐에 대한 참조가 없기 때문에 그리고 당신은 , 아무것도 취소 할 수 없습니다됩니다.) 당신은 지속적인 기준 (예를 들어, 인스턴스 변수/속성)에 gaugeDownloadQueue을 유지하기 위해 필요

. 그렇지 않으면 당신보다 더 많은면에서 당신에게는 쓸모가 없습니다.

또한 AFHTTPRequestOperation 완료 블록이 호출되는 스레드는 무엇입니까? 배경 스레드이고 인터페이스 (예 : updateGaugeTable에 대한 호출)로 인해 문제가 발생하는 경우 당신이 NSOperation을 사용한다는 사실은 당신이 쓰레드에 대한 걱정에 대한 책임을 면제 해줍니다.

+0

여기에 뭔가 백그라운드에서 일어날 수 있도록 NSOperation/NSOperationQueue를 사용하는 방법의 예 : https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch25p865mandelbrotOperation/ch38p1106mandelbrotNoThreading/MyMandelbrotView.m – matt

+0

이것은 의미가 있지만 여전히 주 스레드를 차단하는 것으로 보입니다. UI는 서비스 호출이 반환 될 때까지 여전히 응답하지 않습니다. – Pheepster

+0

알았어.하지만 내가 아는 (예 : AFHTTPRequestOperation) 비 코코아 수업을 사용하고 있는데, 당신이 그들을 오용하지 않는다는 것을 어떻게 알 수 있습니까? 예를 들어, AFHTTPRequestOperation에 대한 완성 블록을 얻었습니다.하지만 호출 된 스레드를 어떻게 알 수 있습니까? 그것이 백그라운드 스레드이고 인터페이스에 대한 작업을하고 있다면 분명히 문제를 일으킬 것입니다. – matt

관련 문제