NSOperation Queue表现异常

Shi*_*ney 7 nsoperation nsoperationqueue grand-central-dispatch ios afnetworking

我的任务是逐个将多个图像上传到服务器.所以我正在使用批处理操作过程.每次我开始上传程序时,一些操作特别是第一个操作一旦启动就完成并且图像没有上传,然后批量上载过程继续正常,并且遗漏了其他图像的罕见故障.

我使用的代码如下: -

-(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];
            }
        }];
    }

}
Run Code Online (Sandbox Code Playgroud)

在此代码中,第一个操作是在我开始上传图像后立即执行,即只有4个中的3个上传.总是遗漏一张图片.也.如果我在网格中只有Image,则上传成功.

谢谢.

Fii*_*iid 2

一些想法...

1)进度更新块。这不会告诉您哪些操作已完成;而是告诉您哪些操作已完成。只是它们的数量,所以我怀疑它们可能没有按照代码认为它们一直在的顺序完成......

2)完成块需要一个操作数组......我想知道这是对所有操作调用一次,还是对已完成的操作数组调用多次?您可以查看数组长度来查看。如果它确实被调用来执行操作子集,那么这将是删除已上传的资产并执行清理工作的地方,因为您知道哪些操作已完成。

3)我会在将操作添加到队列之前设置上传进度块;只是为了安全。

4)我找不到batchOperation方法的文档,并且想知道它是否已从AFNetworking的更新版本中删除 - 如果是的话 - 也许它有错误或不好的API?为了清楚起见,我很想在循环中创建自己的操作;然后进行一些状态管理来检查批次的状态并进行适当的处​​理。

5)你说一个图像总是被遗漏......它是否稳定 - 总是第一个或最后一个?它在 sim 上的行为与在蜂窝网络或模拟的慢速/不可靠连接上的行为是否相同?