我正在尝试使用多线程来实现一系列的http请求,首先我想将几张照片上传到第三方api,并希望所有返回的响应全部收集,然后发出最终的http请求。但是我用以下代码做的事情无法让它发挥作用。
//With valid token, I can upload to a third-party server a list of Photos
//after I have each of the photo uploaded, a "key" is responsed, denoting the name of the Photo
//I would like to collect all the "key", and post to my own server to record them in database
- (void)uploadMultiplePhotoAssets:(NSArray *)assets Token:(NSString *)token
{
dispatch_group_t group = dispatch_group_create();
//I would like to use these arrays to store the result of the following request in each dispatch
__block NSMutableArray *successUploadedImageKeys = [NSMutableArray array];
__block NSMutableArray *failedAssetIndex = [NSMutableArray array];
for(int i= 0; i < assets.count; i++)
{
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
[ThirdPartyApi uploadPHAsset:assets[i] Token:token complete:^(NSString *key) {
if(key)
{ //if key is not nil, the request is successful
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:key forKey:@"key"];
[dict setObject:@(i) forKey:@"index"];
[successUploadedImageKeys addObject:[dict copy]];
}
else
{
//if request failed, record which one failed
[failedAssetIndex addObject:@(i)];
}
}];
});
}
//I would like to handle all the result after each thread is performed, and all the "complete" blocks are also finished
dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
NSLog(@"successUploadedImageKeys is %@, failedAssetIndex is %@", successUploadedImageKeys, failedAssetIndex);
[MyApi postToMyBackend:successUploadedImageKeys];
});
}
如果我使用NSOperation,它也是相同的,在最终的http请求被触发之前不会等待所有complete
块。
在C中,如果编写MPI,则有一种方法可以等待所有线程处于相同状态。在Obj-C中实现这一目的是什么?我如何等待异步响应到达,然后一起做所有响应?
答案 0 :(得分:0)
好老完成处理程序怎么样? (如果需要,由读者决定将任何工作分配到后台线程)
-(void) uploadAsset: (id) asset successKeys: successUploadedImageKeys failedAssets: failedAssetIndex completionHandler: (void(^)(void)) completion {
[ThirdPartyApi uploadPHAsset:assets[i] Token:token complete:^(NSString *key) {
if(key)
{ //if key is not nil, the request is successful
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:key forKey:@"key"];
[dict setObject:@(i) forKey:@"index"];
[successUploadedImageKeys addObject:[dict copy]];
}
else
{
//if request failed, record which one failed
[failedAssetIndex addObject:@(i)];
}
completionHandler(completion);
}];
}
-(void) uploadAssets: (NSMutableSet*) assets token:(NSString *)token successKeys: successUploadedImageKeys failedAssets: failedAssetIndex completionHandler: (void(^)(void)) completion {
id nextAsset = assets.anyObject;
[self uploadAsset: nextAsset successKeys:successUploadedImageKeys failedAssets:failedAssetIndex completionHandler:^{
[assets removeObject:nextAsset];
if (assets.count) {
[self uploadAssets:assets token:token successKeys:successUploadedImageKeys failedAssets:failedAssetIndex completionHandler:completion];
} else {
completion();
}
}];
}
-(void) uploadMultiplePhotoAssets:(NSArray *)assets token:(NSString *)token {
NSMutableArray *successUploadedImageKeys = [NSMutableArray array];
NSMutableArray *failedAssetIndex = [NSMutableArray array];
[self uploadAssets: [NSMutableSet setWithArray:assets] token:(NSString *)token successKeys: successUploadedImageKeys failedAssets: failedAssetIndex completionHandler: (void(^)(void)) {
// done
NSLog(@"successUploadedImageKeys is %@, failedAssetIndex is %@", successUploadedImageKeys, failedAssetIndex);
[MyApi postToMyBackend:successUploadedImageKeys];
}];
}