处理网络时,经常会遇到网络请求相互依赖的情况,如B请求的参数依赖A请求的回调结果,直接在A请求的回调中请求B,会导致回调嵌套,这样导致请求之间紧张耦合。这里介绍一个较优雅的方法:利用NSOperation的操作依赖。
- 本例尝试下载两张图片,假设图片2总是在图片1显示后再显示。
- 下载框架选用AFNetworking3
要使用NSOperation的操作依赖首先需要一个NSOperationQueue:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.name = @"SessionQueue";
由于AFNetworking3中的AFHTTPSessionManager不是NSOperation的子类,这与AFNetworking2有很大不同,不能直接加入NSOperationQueue
,需要封装一下,幸运的是已经有第三方库已经做了所有工作,先引入库:
pod 'AFSessionOperation', :git => 'https://github.com/robertmryan/AFHTTPSessionOperation.git'
AFHTTPSessionOperation
是 NSOperation
的子类,同时调用AFNetworking实现了HTTP 请求,下面是请求操作的实现:
NSString *imangeUrl1 = @"https://upload-images.jianshu.io/upload_images/2025746-368aa3a508d2fbac.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240";
NSString *imangeUrl2 = @"https://upload-images.jianshu.io/upload_images/2025746-27bbf45bea40162c.JPEG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240";
NSOperation *op1 = [AFHTTPSessionOperation operationWithManager:manager HTTPMethod:@"GET" URLString:imangeUrl1 parameters:nil uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"finished 1");
UIImage *image = [UIImage imageWithData:responseObject];
_imageView1.image = image;
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"failed 1 - error = %@", error.localizedDescription);
}];
NSOperation *op2 = [AFHTTPSessionOperation operationWithManager:manager HTTPMethod:@"GET" URLString:imangeUrl2 parameters:nil uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"finished 2");
UIImage *image = [UIImage imageWithData:responseObject];
_imageView2.image = image;
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"failed 2 - error = %@", error.localizedDescription);
}];
op2依赖op1:
[op2 addDependency:op1];
最后将op1、op2添加到操作队列中,这会开始执行网络请求:
[queue addOperations:@[op1, op2] waitUntilFinished:false];
执行结果:
按照我们的设计,op2在op1完成后才执行。
使用时注意不要造成依赖环
,像这样:
[op1 addDependency:op2];
[op2 addDependency:op1];
这样两个操作都不会执行。