需求:异步上传5张图片到服务器A,上传成功后将返回的url以及相关信息传给服务器B?!颈V?上传给B的url顺序与图片的上传顺序相同】
方法1:
- (void)semaphoreA{
NSLog(@"============= semaphoreA =======");
NSArray *arr = @[@"aaa",@"bbb",@"ccc",@"ddd"];
//有同时被写入数据的情况 需要加线程锁 此处用dispatch_semaphore_t锁住 以保证数据安全
NSMutableArray *addedArray = [NSMutableArray array];
dispatch_semaphore_t semaLock = dispatch_semaphore_create(1);
NSMutableArray *replaceArray = [NSMutableArray arrayWithArray:arr];
for (int i = 0; i < arr.count; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSObject *obj = [arr objectAtIndex:i];
sleep(2);
NSLog(@"image %@ index %tu has uploaded",obj,i);
NSString *newObj = [NSString stringWithFormat:@"%@_%tu",obj,i];
[replaceArray replaceObjectAtIndex:i withObject:newObj];
dispatch_semaphore_wait(semaLock, DISPATCH_TIME_FOREVER);
[addedArray addObject:newObj];
dispatch_semaphore_signal(semaLock);
if(addedArray.count == arr.count){
NSLog(@"done");
NSLog(@"replaceArray = %@",replaceArray);
NSLog(@"addedArray = %@",addedArray);
}
});
}
}
方法2.
- (void)semaphoreAA{
NSLog(@"============= semaphoreAA =======");
NSArray *arr = @[@"aaa",@"bbb",@"ccc",@"ddd"];
//有同时被写入数据的情况 需要加线程锁 此处用dispatch_semaphore_t锁住 以保证数据安全
NSMutableArray *addedArray = [NSMutableArray array];
dispatch_semaphore_t semaLock = dispatch_semaphore_create(1);
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
NSMutableArray *replaceArray = [NSMutableArray arrayWithArray:arr];
for (int i = 0; i < arr.count; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSObject *obj = [arr objectAtIndex:i];
sleep(2);
NSLog(@"image %@ index %tu has uploaded",obj,i);
NSString *newObj = [NSString stringWithFormat:@"%@_%tu",obj,i];
[replaceArray replaceObjectAtIndex:i withObject:newObj];
dispatch_semaphore_wait(semaLock, DISPATCH_TIME_FOREVER);
[addedArray addObject:newObj];
dispatch_semaphore_signal(semaLock);
if(addedArray.count == arr.count){
dispatch_semaphore_signal(sema);
}
});
}
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"done");
NSLog(@"replaceArray = %@",replaceArray);
NSLog(@"addedArray = %@",addedArray);
}
用两个数组是为了显示 add方法图片顺序问题。
在实际的上传图片网络请求中,往往会有成功&失败两个回调,用上述方法都需要一个计数量判断,麻烦易出错不说还显得很不美观,于是有了方法3.
方法3:
- (void)groupA{
NSLog(@"============= groupA =======");
dispatch_group_t group = dispatch_group_create();
NSArray *arr = @[@"aaa",@"bbb",@"ccc",@"ddd"];
//有同时被写入数据的情况 需要加线程锁 此处用dispatch_semaphore_t锁住 以保证数据安全
NSMutableArray *addedArray = [NSMutableArray array];
dispatch_semaphore_t semaLock = dispatch_semaphore_create(1);
NSMutableArray *replaceArray = [NSMutableArray arrayWithArray:arr];
for (int i = 0; i < arr.count; i++) {
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSObject *obj = [arr objectAtIndex:i];
sleep(2);
NSLog(@"image %@ index %tu has uploaded",obj,i);
NSString *newObj = [NSString stringWithFormat:@"%@_%tu",obj,i];
[replaceArray replaceObjectAtIndex:i withObject:newObj];
dispatch_semaphore_wait(semaLock, DISPATCH_TIME_FOREVER);
[addedArray addObject:newObj];
dispatch_semaphore_signal(semaLock);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
//会阻碍主线程
// dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"done");
NSLog(@"replaceArray = %@",replaceArray);
NSLog(@"addedArray = %@",addedArray);
});
}
如果是成功失败回调,则
success{
dispatch_semaphore_signal(sema);
}failure{
dispatch_semaphore_signal(sema);
}
参考资料:iOS之利用GCD信号量控制并发网络请求