2017-10-13 6 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は、デフォルトでキャンセルをサポートしていません。クラスのドキュメントを参照してください。 1つの抽出は次のとおりです。

操作をキャンセルしても、直ちにその操作が強制的に停止されるわけではありません。キャンセルされたプロパティの値をすべての操作で期待していますが、コードはこのプロパティの値を明示的にチェックし、必要に応じて中止する必要があります。

NSBlockOperationを使用してキャンセルを実装することも難しいようです。

+0

クイック返信ありがとうございます。 NSBlockOperationのほかに何が使えますか? – Lee

関連する問題