2017-10-13 4 views
0

NSOperationQueue에서 모든 작업을 취소하는 방법은 무엇입니까? cancelAllOperations 메서드를 사용했지만 작동하지 않았습니다. NSOperationQueue는 여전히 서버를 호출하여 사진을 업로드합니다.NSOperationOperationQueue cancelAllOperations 메서드가 작업을 중지하지 않습니다.

루프마다 NSOperationQueue에 모든 단일 연결을 적용했습니다.

- (void)sendingImage:(NSArray *)imgArray compression:(CGFloat)compression 
{  
    hud = [MBProgressHUD showHUDAddedTo: self.view animated: YES]; 
    hud.label.text = [NSString stringWithFormat: @"Waiting for Loading"]; 
    [hud.button setTitle: @"Cancel" forState: UIControlStateNormal]; 
    [hud.button addTarget: self action: @selector(cancelWork:) forControlEvents: UIControlEventTouchUpInside]; 

    __block int photoFinished = 0; 

    self.queue = [[NSOperationQueue alloc] init]; 
    self.queue.maxConcurrentOperationCount = 5; 
    [self.queue addObserver: self forKeyPath: @"operations" options: 0 context: NULL]; 

    NSBlockOperation *operation = [[NSBlockOperation alloc] init]; 
    __weak NSBlockOperation *weakOperation = operation;  
    __block NSString *response = @""; 

    for (int i = 0; i < imgArray.count; i++) { 

     operation = [NSBlockOperation blockOperationWithBlock:^{ 
      [self uploadingPhoto]; 
     }]; 

     [operation setCompletionBlock:^{ 
      NSLog(@"Operation 1-%d Completed", i); 
      photoFinished++; 

      dispatch_async(dispatch_get_main_queue(), ^{ 
       hud.label.text = [NSString stringWithFormat: @"%d photo complete uploading", photoFinished]; 
      }); 
     }]; 

     [self.queue addOperation: operation]; 
    } 
} 

내가 먼저 모든 NSURLSessionDataTask 취소하고 모든 작업을 취소 MBProgressHUD에 취소 버튼을 누르세요,하지만 작동하지 않았다.

- (void)cancelWork:(id)sender { 
    NSLog(@"cancelWork");  
    NSLog(@"self.queue.operationCount: %lu", (unsigned long)self.queue.operationCount); 

    [session getTasksWithCompletionHandler:^(NSArray<NSURLSessionDataTask *> * _Nonnull dataTasks, NSArray<NSURLSessionUploadTask *> * _Nonnull uploadTasks, NSArray<NSURLSessionDownloadTask *> * _Nonnull downloadTasks) { 

     if (!dataTasks || !dataTasks.count) { 
      return; 
     } 
     for (NSURLSessionDataTask *task in dataTasks) { 
      [task cancel]; 

      if ([self.queue operationCount] > 0) { 
       [self.queue cancelAllOperations]; 
      } 
     } 
    }]; 
} 

NSURLSession이 동기 연결이되도록하기 위해 세마포어를 사용했습니다.

- (void)uploadingPhoto { 

    request setting above 

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    config.timeoutIntervalForRequest = 1200; 

    session = [NSURLSession sessionWithConfiguration: config]; 

    dataTask = [session dataTaskWithRequest: request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

     if (error == nil) { 
      str = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 
      NSLog(@"str: %@", str); 
     } 

     dispatch_semaphore_signal(semaphore); 
    }]; 
    NSLog(@"task resume"); 
    [dataTask resume]; 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    return str; 
} 

모든 의견이나 해결책을 보내 주시면 대단히 감사하겠습니다.

답변

1

NSOperation에는 기본적으로 취소 지원이 없습니다. 클래스 문서를 참조하십시오. 하나의 추출물은 다음과 같습니다.

작업을 취소해도 작업이 즉시 중단되지 않습니다. 취소 된 속성의 값을 존중하는 것은 모든 작업에서 발생하지만 코드에서이 속성의 값을 명시 적으로 확인하고 필요에 따라 중단해야합니다.

또한 NSBlockOperation을 사용하여 취소를 구현하는 것이 어려워 보입니다.

+0

빠른 답장을 보내 주셔서 감사합니다. NSBlockOperation 옆에 내가 뭘 사용할 수 있습니까? – Lee

관련 문제