2017-10-13 87 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]; 
    } 
} 

我想按取消MBProgressHUD按鈕來取消首所有NSURLSessionDataTask然後取消所有的操作,但沒有奏效。

- (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