RequestQueue 是一个用于管理应用程序中多个并发异步 URL 请求的简单类。
注意:'支持' 表示库已与该版本进行了测试。'兼容' 表示此库应能在该操作系统版本上运行(即它不依赖于任何不可用的 SDK 功能),但不再进行兼容性测试,可能需要调整或修复错误才能正确运行。
从版本 1.5 开始,RequestQueue 需要 ARC。如果您想在非 ARC 项目中使用 RequestQueue,只需将 -fobjc-arc 编译器标志添加到 RequestQueue.m 类中。要这样做,请转到目标设置中的构建阶段选项卡,打开编译源代码组,在列表中双击 RequestQueue.m,然后在弹出窗口中输入 -fobjc-arc。
如果您希望将整个项目转换为 ARC,请注释掉 RequestQueue.m 中的 #error 行,然后运行 Xcode 中的编辑 > 重构 > 转换为 Objective-C ARC... 工具,并确保您希望使用 ARC 的所有文件都已勾选(包括 RequestQueue.m)。
您可以在任何线程上创建 RQOperation 和 RequestQueue 实例,但每个实例的方法应仅在单个线程上调用。此外,主队列的共享实例应仅在主线程上使用。
要在应用程序中使用 RequestQueue,只需将 RequestQueue 类文件拖放到您的项目中。RequestQueue 没有依赖项。
RequestQueue 库由两个主要类组成,即 RQOperation 和 RequestQueue 本身。
RQOperation 是一个 NSOperation 子类,它包装了一个异步 NSURLConnection。您可以使用 RQOperation 单独使用它来制作独立的异步请求,或者将其添加到任何普通的 NSOperationQueue 中。
RequestQueue 简化了 RQOperations 队列的管理,并允许使用 NSOperationQueue 无法实现的特性,例如 LIFO(后进先出)队列(具体细节请参见下文)。
@property (nonatomic, strong, readonly) NSURLRequest *request;
用于初始化操作的原始 NSUserDefaultsRequest。NSURLConnection 会对它进行深度复制,因此创建 RQOperation 后对请求的任何更改都不会影响 RQOperation,但保留对该请求的引用可能有助于以后识别 RQOperation。
@property (nonatomic, copy) RQCompletionHandler completionHandler;
当请求完成、失败或取消时将调用的代码块。有关回调参数的详细信息,请参阅下面的“回调”部分。
@property (nonatomic, copy) RQProgressHandler uploadProgressHandler;
当 NSURLConnection 发送上传数据时将定期调用的代码块。当向服务器传输大文件并希望显示进度条时,此功能非常有用,但通常不适用于大多数请求。有关回调参数的详细信息,请参阅下面的“回调”部分。
@property (nonatomic, copy) RQProgressHandler downloadProgressHandler;
当 NSURLConnection 下载数据时将定期调用的代码块。当从服务器下载大文件并希望显示进度条时,此功能非常有用。有关回调参数的详细信息,请参阅下面的“回调”部分。
@property (nonatomic, copy) RQAuthenticationChallengeHandler authenticationChallengeHandler;
在服务器返回身份验证挑战的情况下将调用的代码块。
@property (nonatomic, copy) NSSet *autoRetryErrorCodes;
当决定是否应自动重试请求时要比较的错误代码集。默认情况下,此集合包括与连接不佳或不可用相关的任何 NSURLError 类型。这意味着如果互联网断开或连接超时,操作会重试,但如果 UL 格式不正确或资源不存在,则不会重试(这是没有意义的)。如有必要,您可以自定义此集合以满足应用程序的具体需求。
@property (nonatomic) NSTimeInterval autoRetryDelay;
如果启用 autoRetry,则在请求重新尝试之前将会有延迟。默认值为 5 秒。
@property (nonatomic) BOOL autoRetry;
如果设置为 YES
,则当发生连接失败时,将自动重试而不是终止并调用 completionHandler。操作将比较错误代码与 autoRetryErrorCodes 集合,并且只有在集合中存在该代码时才会重试。默认值为 NO
。
+ (RQOperation *)operationWithRequest:(NSURLRequest *)request;
- (RQOperation *)initWithRequest:(NSURLRequest *)request;
这些方法用于创建新的请求操作。RQOperations 是一次性的,这意味着在操作创建后不能更改请求,并且操作只能用于发送请求的单个实例,之后应该将其丢弃。
@property (nonatomic) NSUInteger maxConcurrentRequestCount;
并发请求的最大数量。如果添加到队列的请求多于这个数量,它们将排队等待之前的请求完成。0 的值意味着没有对并发请求数量的限制。1 的值意味着一次只有一个请求是活动的,并确保请求按它们添加的顺序完成(假设 queueMode
是 RequestQueueModeFirstInFirstOut
)。默认值为 2。
@property (nonatomic, getter = isSuspended) BOOL suspended;
此属性切换是否启动队列中的请求。正在进行的请求不会受到此属性切换的影响,但如果 suspended = YES,则不会开始新的请求,直到将其设置为 NO。将此属性设置为 NO 将立即开始下载下一个排队的请求。
@property (nonatomic, readonly) NSUInteger requestCount;
队列中的请求数量。这包括活动请求和待处理请求。
@property (nonatomic, copy, readonly) NSArray *requests;
队列中的请求。这包括活动请求和待处理请求。
@property (nonatomic) RequestQueueMode queueMode;
queueMode 属性控制新请求是否添加到队列的头部或尾部。默认值 RequestQueueModeFirstInFirstOut
将新请求添加到队列尾部,而 RequestQueueModeLastInFirstOut
将它们添加到队列头部。先进先出意味着近期请求获得优先权。已激活的请求仍将首先完成,但如果队列中积压了大量请求,新的请求则不需要等待积压请求清除后再处理。
@property (nonatomic) BOOL allowDuplicateRequests;
此属性用于控制请求队列是否允许添加多个相同的请求。如果设置为 NO
(默认值),则添加重复请求(即参数与队列中另一个请求相同的请求)会导致之前添加的请求被取消。取消请求的完成处理程序将像往常一样使用 NSURLErrorCancelled 错误调用。
RequestQueue 类有以下方法
+ (RequestQueue *)mainQueue;
这返回请求队列的单例共享实例,可用于您的应用程序的任何地方(不是线程安全的,应该只从主线程调用)。也可以创建自己的队列实例以更精细地控制并发(例如,您可以为低优先级创建一个队列实例,并为高优先级创建一个实例,以便您的应用程序在高优先级请求得到处理而不被低优先级请求阻塞,等待其完成)。
- (void)addOperation:(RQOperation *)operation;
这将在队列中添加新的 RQOperation。如果在队列中已有少于 maxConcurrentRequestCount
的操作,这会立即启动。多次添加相同的 RQOperation 到队列中是不有效的(这将抛出异常),但是您可以使用不同的 RQOperation 实例多次向给定的队列添加相同的请求。请注意,尽管 RQOperation 是按添加顺序启动的(先进先出),但其完成顺序没有保证,除非将 maxConcurrentRequestCount
设置为 1。
- (void)addRequest:(NSURLRequest *)request completionHandler:(RQCompletionHandler)completionHandler;
这将以指定的完成处理程序创建一个新的 RQOperation并将其添加到队列中。请注意,相同的请求可以多次添加到队列中,并且会被下载多次。如果您想避免将重复请求添加到队列中多次,则在添加之前,使用 NSArray 的 contains:
方法检查队列的 requests
属性是否已包含一个相同的请求。
- (void)cancelRequest:(NSURLRequest *)request;
如果请求正在进行,此方法将取消请求并从队列中删除它。无论请求是否已开始,完成处理程序块都将接收到错误代码 NSURLErrorCancelled
。 注意: 为了取消 RQOperation,只需要直接调用操作对象的 cancel 方法,它将自动从任何已添加到其队列中删除它。
- (void)cancelAllRequests;
此方法将取消所有活动请求和队列中的请求,并将其从队列中删除。
RequestQueue 定义以下回调块函数,您可以使用它们通知请求的状态和进度。
typedef void (^RQCompletionHandler)(NSURLResponse *response, NSData *data, NSError *error);
请求下载完成后,您的回调将使用这些参数调用。如果请求成功,错误参数将为 nil。发生错误时,响应和数据可能为 nil 或根据错误的性质而有所不同。如果请求被取消,错误代码将为 NSURLErrorCancelled
。
typedef void (^RQProgressHandler)(float progress, NSInteger bytesTransferred, NSInteger totalBytes);
此回调用于跟踪请求上传或下载的进度。进度参数是一个介于 0.0 和 1.0 之间的浮点数,用于更新进度条或其他视觉进度指示器。已传输的字节和总字节数参数分别指示已传输的字节数和预计要传输的总字节数。注意:总字节数通常是一个估算值,有时可能不准确,或者不可用(在这种情况下,值可能为零或 -1)。在这些情况下,进度值没有意义,您应该显示一个不确定的进度指示器,例如旋转器(UIActivityIndicatorView)或理发师带。
版本 1.5.3
版本 1.5.2
版本 1.5.1
版本 1.5
版本 1.4.1
版本 1.4
版本 1.3
版本 1.2
版本 1.1.1
版本 1.1
版本 1.0