图片异步批量上传 原理:通过 gcd 的线程组 去实现异步并发 通过 gcd 的信号量 去控制并发数量 最后通过 线程组的监听函数 做统一回调
/// 图片组异步并发上传
/// @param images 图片组
/// @param num 最大并发数量
/// @param success 每成功上传一张图片都会回调
/// @param failure 每上传失败一张图片都会回调
/// @param finish 所有图片都上传完成后回调
- (void)uploadImages:(NSArray<UIImage *>*)images asyncNum:(NSInteger)num successForImage:(void (^)(id data, NSInteger imageIdx))success failureForImage:(void (^)(NSString *msg, NSInteger imageIdx))failure allFinish:(void(^)(void))finish {
/*
由于不确定外部调用时在哪个线程内,为了防止线程死锁 需要自定义一个并发队列
*/
dispatch_queue_t myQueue = dispatch_queue_create("uploadImage.queue.com", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create((num <= 0 ? 0 : num));
dispatch_group_t group = dispatch_group_create();
[images enumerateObjectsUsingBlock:^(UIImage * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_enter(group);
/*
单张图片上传逻辑,这里替换成自己的单张图片处理逻辑即可
*/
[self uploadImage:obj success:^(id _Nonnull data) {
if (success) {
success(data, idx);
}
//成功时必须调用
dispatch_group_leave(group);
dispatch_semaphore_signal(semaphore);
} failure:^(NSString * _Nonnull msg) {
if (failure) {
failure(msg, idx);
}
//失败时必须调用
dispatch_group_leave(group);
dispatch_semaphore_signal(semaphore);
}];
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
if (finish) {
finish();
}
});
});
}