優雅地處理網路請求的依賴關係
處理網路時,經常會遇到網路請求相互依賴的情況,如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];
這樣兩個操作都不會執行。