文章目录
前言:
前阵子遇到七牛文件批量上传的问题,尝试了几种方案,现分享一种目前采用的方案——自定义operation。
为什么要自己实现七牛文件的批量上传
在使用七牛云存储服务的过程中,想要在手机客户端进行图片、视频等文件的上传,只需要直接引入SDK,然后使用QiniuSDK即可。对于iOS端的上传特别简单,只需要使用pod引入SDK:
pod "Qiniu", "~> 7.0"
然后
#import <QiniuSDK.h>
...
NSString *token = @"从服务端SDK获取";
QNUploadManager *upManager = [[QNUploadManager alloc] init];
NSData *data = [@"Hello, World!" dataUsingEncoding : NSUTF8StringEncoding];
[upManager putData:data key:@"hello" token:token
complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
NSLog(@"%@", info);
NSLog(@"%@", resp);
} option:nil];
...
十分简单的操作就能实现。
然而这种使用方法仅适用于单个或少量的文件上传,一旦文件数量较多,就会出现网络资源竞争导致超时或者其他问题,使文件上传失败。
这是由于这种方式会直接创建一个上传任务,同时开启的任务会同时执行。
如何实现七牛文件批量上传
直接使用七牛SDK创建上传任务的问题在于创建多少执行多少,网络资源被竞争而导致失败。
解决这个问题的关键就是控制上传任务同时执行的个数,保证网络充分利用,又没有过多的竞争。
可选方案:
-
手工创建一个上传任务待执行池(数组),控制执行池的任务数量
创建文件上传任务的同时,将需要上传的文件(路径)放入一个临时数组,文件上传结束后,从数组中移除这个文件(路径)。
设置同时上传任务最大数量,每次创建新任务之前检查数组中的文件数,没有达到最大数量时允许创建,反之不允许创建。
-
自定义NSOperation,将operation加入queue做并发控制
将每个上传任务封装成一个NSOperation,直接加入NSOperationQueue实例,同时设置最大并发数。
-
GCD中的dispatch_semaphore_t来控制任务执行数量。
设置信号量阈值为同时执行的上传任务最大数量,每创建一个任务前wait信号,每完成一个发送signal。
最优方案:
以上三种方案,都能解决批量文件上传与网络资源竞争的问题。
不过方案1需要控制数组的多线程访问(加锁),方案3也需要维护一个全局的dispatch_semaphore_t实例,同时方案1和3都不支持任务取消。
而方案2直接使用NSOperationQueue可以很方便的取消所有任务。处理一些用户的退出登录等动作就很容易。
方案2最优。
#自定义NSOperation
-
基本概念
NSOperation用于iOS的多线程编程中,我们想要执行一个异步任务,可以将这个任务封装成一个NSOperation,创建这个NSOperation实例,并启动就可以达到异步执行的目的。
NSOperation是一个抽象类,不能直接实例化。
我们想使用NSOperation来执行具体任务,就必须创建NSOperation的子类或者使用系统预定义的两个子类,NSInvocationOperation和 NSBlockOperation。
-
几个要点
-
NSOperation有几个执行状态:
官方文档ey P