NSOperationOperationQueue cancelAllOperations方法不会停止操作

NSOperationOperationQueue cancelAllOperations方法不会停止操作

问题描述:

如何取消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; 
} 

任何意见或解决方案将不胜感激。

NSOperation默认情况下不支持取消。请参阅班级文件。一个摘录是:

取消操作不会立即强制停止它正在执行的操作。尽管在取消属性中尊重所有操作的值,但您的代码必须显式检查此属性中的值并根据需要中止。

这似乎也很难实施取消使用NSBlockOperation

+0

感谢您的快速回复。除了NSBlockOperation,还有什么可以使用的? – Lee