7

Mam zadanie przesyłania wielu obrazów na serwer jeden po drugim. Używam do tego procesu operacji wsadowej. Za każdym razem, gdy zaczynam procedurę ładowania, niektóre operacje, szczególnie te, które wykonałem, rozpoczynają się zaraz po uruchomieniu, a obraz nie zostanie przesłany, a następnie proces ładowania wsadu przebiega w porządku z rzadkim brakiem innych obrazów.Kolejka NSOperation zachowuje się niepoprawnie

Kod używam jest następująco: -

-(void)callWSToUploadRxs{ 


    NSLog(@"the total assets maintained are %lu", (unsigned long)_arr_assetsMaintained.count); 

    NSMutableArray *mutableOperations = [NSMutableArray array]; 
    int imageUploadCount = (int)[self extractFullSizeImagesToUpload].count; 
    // second for loop is to initialize the operations and then queue them. 
    for (int i = 0; i<imageUploadCount; i++) { 


     NSData *imageData = UIImageJPEGRepresentation([_arr_originalImagesToSend objectAtIndex:i],1.0); 

     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
     [request setHTTPMethod:@"POST"]; 

     NSLog(@"the url constructed is %@", [NSString stringWithFormat:@"%@/%@/%@/%@",uploadRxUrl,@"4004DD85-1421-4992-A811-8E2F3B2E49F7",@"5293",[_arr_imageNames objectAtIndex:i]]); 
     [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@/%@.jpg",uploadRxUrl,@"4004DD85-1421-4992-A811-8E2F3B2E49F7",@"5293",[_arr_imageNames objectAtIndex:i]]]]; 
     [request setValue:@"binary/octet-stream" forHTTPHeaderField:@"Content-Type"]; 

     [request setHTTPBody:imageData]; 
     AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 

     [mutableOperations addObject:operation]; 
    } 

    currentUploadIndex++; 
    NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:mutableOperations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { 
     NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations); 

     NSIndexPath * indexOfImageTobeDeleted = [_selectedItemsIndexPaths objectAtIndex:0];//numberOfFinishedOperations-1 
     [_arr_assetsMaintained removeObjectAtIndex:indexOfImageTobeDeleted.item]; 
     [_arr_images removeObjectAtIndex:indexOfImageTobeDeleted.item]; 
     [_arr_fullSizeImages removeObjectAtIndex:indexOfImageTobeDeleted.item]; 
     [_arr_imageNames removeObjectAtIndex:indexOfImageTobeDeleted.item]; 

     if ([_arr_selectedCells containsObject:[NSString stringWithFormat:@"%ld",(long)indexOfImageTobeDeleted.item]] ) 
     { 
      [_arr_selectedCells removeObject:[NSString stringWithFormat:@"%ld",(long)indexOfImageTobeDeleted.item]]; 
      //[cell.img_selctedRxs setHidden:TRUE]; 


     } 
     countBeforeClearingAssets = countBeforeClearingAssets - 1; 
     //Reload the items of UICollectionView performBatchUpdates Block 
     [_albumImagesCollection performBatchUpdates:^{ 
      [_albumImagesCollection deleteItemsAtIndexPaths:@[indexOfImageTobeDeleted]]; 
     } completion:nil]; 

     _selectedItemsIndexPaths = [_albumImagesCollection indexPathsForSelectedItems]; 
     // [_selectedItemsIndexPaths removeObjectAtIndex:0]; 
     NSLog(@"the count of selected items after updation is %lu", (unsigned long)_selectedItemsIndexPaths.count); 


    } completionBlock:^(NSArray *operations) { 
     NSLog(@"All operations in batch complete"); 
     [self callWSToAddNoteForRxs]; 
     [_arr_originalImagesToSend removeAllObjects]; 
     [_arr_selectedCells removeAllObjects]; 
     currentUploadIndex = 0; 
     NSLog(@"the array of image names is %@",_arr_imageNames); 
    }]; 

    [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO]; 

    // third is to maintain the progress block for each image to be uploaded one after the other. 
    for (AFHTTPRequestOperation *operation in mutableOperations){ 

     [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { 

      [_progressOverLayView setAlpha:0.7f]; 
      [_progressView setHidden:FALSE]; 
      [_progressView setProgress: totalBytesWritten*1.0f/totalBytesExpectedToWrite animated: YES]; 
      [_lbl_progressUpdate setHidden:FALSE]; 
      _lbl_progressUpdate.text = [NSString stringWithFormat:@"Image %d of %lu uploading", currentUploadIndex, mutableOperations.count]; 
      NSLog(@"Sent %lld of %lld bytes and progress is %f", totalBytesWritten, totalBytesExpectedToWrite, totalBytesWritten*1.0f/totalBytesExpectedToWrite); 
      if(totalBytesWritten >= totalBytesExpectedToWrite) 
      { 
       //progressView.hidden = YES; 
       [self setComplete]; 
      } 
     }]; 
    } 

} 

W tym kodzie pierwsza operacja jest uzyskiwanie wykonywane zaraz zacznę przesyłając obrazy tj tylko 3 spośród 4 są przesyłane coraz. Jeden obraz jest zawsze pomijany. Również. jeśli mam tylko obraz w siatce, to ładuje się pomyślnie.

Dzięki.

+0

Czy ktoś ma realistyczne rozwiązanie tego problemu? –

+0

Czy obraz, który jest pominięty w procesie przesyłania, jest nadal usunięty z albumuImages? A także, jest to pierwszy obraz, który został pominięty lub ostatni? – user2695712

+0

Tak, jest pominięty i kończy się blok ukończenia tego obrazu, który faktycznie usuwa go z widoku kolekcji. Jest to głównie pierwszy obraz z dwóch w 95% przypadków i 2 obrazy w przypadku 4 lub więcej i tak dalej. H: Zidentyfikowałeś już problem? –

Odpowiedz

2

Kilka myśli ...

1) blok aktualizacji postępu. To nie mówi, które operacje zostały zakończone; tylko ich liczba, więc podejrzewam, że mogą nie być kompletne w kolejności, w której kod myśli, że są cały czas ...

2) blok ukończenia ma szereg operacji .... I Zastanawiam się, czy zostanie to wywołane raz ze wszystkimi operacjami lub wiele razy z tablicami zakończonych operacji? Możesz zobaczyć długość tablicy, aby zobaczyć. Jeśli zostanie wywołany dla podzbiorów operacji, będzie to miejsce do usunięcia zasobów, które już zostały przesłane i czyszczenie, ponieważ wiesz, które operacje zostały zakończone.

3) Ustawię blok postępu przesyłania przed dodaniem operacji do kolejki; tylko dla bezpieczeństwa.

4) Nie mogłem znaleźć dokumentacji dla metody batchOperation i zastanawiałem się, czy została ona usunięta z nowszej wersji AFNetworking - a jeśli tak, to może jest to buggy lub nie dobry interfejs API? Kusiłabym się, by tworzyć własne operacje w pętli dla jasności; a następnie wykonaj małe zarządzanie stanem, aby sprawdzić status partii i odpowiednio ją obsłużyć.

5) Mówisz, że jedno zdjęcie jest zawsze pomijane .... czy jest stabilne - zawsze pierwsze czy ostatnie? Czy zachowuje się w ten sam sposób na symulatorze vs sieci komórkowej lub symulowanym wolnym/zawodnym połączeniu?

+0

1. Mówi, która operacja jest zakończona: - currentUploadIndex jest zmienną. 2. Blok zakończenia zawsze wykonuje się tylko raz, gdy wszystkie operacje zostaną zakończone. 3. Gdzie powinienem przechowywać blok postępu w kodzie zgodnie z sugestiami? 4. Czy możesz pokazać mały kod swojego podejścia? 5. jest bardzo losowy, ale zachowuje się tak samo w każdej sieci komórkowej. Proszę zasugerować sposób, aby wydostać się z tego wszystkiego. –

Powiązane problemy