一、基本简介
一直想要把自己这几年的相关的工作上遇到的知识点通过文字整理出来,但是一直不想写,不知道是不是一直以来对于作文的恐惧,但最近闲来无事做,正式开始我的码字生涯。笔者:七禾。
二、联系方式
这也是我的第一篇文章,有不对和欠缺的地方望各位大神不吝赐教。个人联系QQ:1218424215。若我不在请发我邮箱,不甚感激。
三、问题需求
写此文的初衷也是我的一位iOS朋友提出的一个需求,应该算是问题吧。
问题:在同一个页面发送了三个AFN请求,但是服务器reponse回来后就会发生数据错乱的情况,所以故此提出想要让发送的AFN请求能够有依赖,即下一个请求在上一个请求响应完成后再发送数据请求。
四、思路探讨
这个AFN的原理和异步请求我就不说了,然后我主要说我的解题思路吧。
我的第一个想到的是依赖关系,有GCD和NSOperation两种。
五、GCD依赖
1>普通的依赖关系:话不多说,看代码,先行运行看效果
代码如下:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self addBtn1];
}
- (void)addBtn1{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 100, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"普通的组依赖" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn1) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn1{
[self normalGroup];
}
- (void)normalGroup{
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"正常方法执行1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"正常方法执行2");
});
dispatch_group_async(group, queue, ^{
NSLog(@"正常方法执行3");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"正常方法执行4");
dispatch_async(dispatch_get_main_queue(), ^{
//刷新UI code here...
});
});
});
}
@end
效果:这个一定会等到所有的前面的3个任务执行完毕,再执行最后一个任务即任务4,但是前面的3个任务不是按顺序执行的,是无序的。即效果不达预期。
2>改进版:将前面三个任务统一放在一个异步线程中,那样就达到预期了
代码如下:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// [self addBtn1];
[self addBtn2];
}
- (void)addBtn2{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 200, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"普通改进版" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn2) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn2{
[self normalGroupModify];
}
- (void)normalGroupModify{
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"正常方法执行1");
NSLog(@"正常方法执行2");
NSLog(@"正常方法执行3");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"正常方法执行4");
dispatch_async(dispatch_get_main_queue(), ^{
//刷新UI code here...
});
});
});
}
@end
效果:这肯定就是前三个任务执行完毕后,后面的任务4结束,但是如果是AFN请求呢?
3>组中的执行AFN异步请求,也是先上代码,我用写好的一个工具类
代码如下:
工具类代码:
//KODAFNTool类的头文件
#import <Foundation/Foundation.h>
@interface KODAFNTool : NSObject
+ (void)get:(NSString *)url
params:(NSDictionary *)params
success:(void(^)(id response))success
failure:(void(^)(NSError *error))failure;
+ (void)post:(NSString *)url
params:(NSDictionary *)params
success:(void(^)(id response))success
failure:(void(^)(NSError *error))failure;
@end
//KODAFNTool类的实现
#import "KODAFNTool.h"
#import "AFNetworking.h"
@implementation KODAFNTool
+ (void)get:(NSString *)url
params:(NSDictionary *)params
success:(void(^)(id response))success
failure:(void(^)(NSError *error))failure
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"image/jpeg",@"text/html",@"text/plain", nil];
[manager GET:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) failure(error);
}];
}
+ (void)post:(NSString *)url
params:(NSDictionary *)params
success:(void(^)(id response))success
failure:(void(^)(NSError *error))failure
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"image/jpeg",@"text/html",@"text/plain", nil];
[manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) failure(error);
}];
}
@end
//ViewController中的实现代码:其中注释掉了两个按钮方法,还有就是导入了工具类KODAFNTool.h
#import "ViewController.h"
#import "KODAFNTool.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//[self addBtn1];
//[self addBtn2];
[self addBtn3];
}
- (void)addBtn3{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 300, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"组中AFN请求" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn3) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn3{
[self afnTest1];
}
- (void)afnTest1{
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_async(group, queue, ^{
NSString *urlString1 = @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3495161387,2602242859&fm=23&gp=0.jpg";
[self AFNRequestWithUrlString:urlString1 message:@"dispatch_group_enter请求1" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求1, json = %@",json);
NSLog(@"最终成功完成了请求1");
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求1,error = %@",error);
}];
NSString *urlString2 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=979daec634bebdcbb3c14792a2f1fe83&imgtype=0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F121209%2F234928-12120Z0543764.jpg";
[self AFNRequestWithUrlString:urlString2 message:@"dispatch_group_enter请求2" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求2, json = %@",json);
NSLog(@"最终成功完成了请求2");
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求2,error = %@",error);
}];
NSString *urlString3 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=76092dbeceb09618622fd7993510c9fb&imgtype=0&src=http%3A%2F%2Fmvimg1.meitudata.com%2F55e2b8683d7464031.jpg";
[self AFNRequestWithUrlString:urlString3 message:@"dispatch_group_enter请求3" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求3, json = %@",json);
NSLog(@"最终成功完成了请求3");
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求3,error = %@",error);
}];
NSString *urlString4 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=dd23514c28fc192b9aff3b5d0fc79392&imgtype=0&src=http%3A%2F%2Fscimg.jb51.net%2Fallimg%2F160403%2F13-1604032125201L.jpg";
[self AFNRequestWithUrlString:urlString4 message:@"dispatch_group_enter请求4" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求4, json = %@",json);
NSLog(@"最终成功完成了请求4");
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求4,error = %@",error);
}];
NSString *urlString5 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=3edc9455c16e8aab5c2ca3d3852104e5&imgtype=0&src=http%3A%2F%2Fmvimg2.meitudata.com%2F5561a1904d4424767.jpg";
[self AFNRequestWithUrlString:urlString5 message:@"dispatch_group_enter请求5" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求5, json = %@",json);
NSLog(@"最终成功完成了请求5");
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求5,error = %@",error);
}];
});
//当所有队列执行完成之后
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//返回主线程刷新
NSLog(@"主线程刷新UI");
});
}
- (void)AFNRequestWithUrlString:(NSString *)urlString message:(NSString *)message withSuccessBlock:(void(^)(id response))success errorBlock:(void(^)(NSError *error))errorBlock
{
NSLog(@"需要拿参%@",message);
[KODAFNTool get:urlString params:nil success:^(id response) {
NSLog(@"%@",message);
success(response);
} failure:^(NSError *error) {
NSLog(@"%@",message);
errorBlock(error);
}];
}
@end
效果:
4>重点来了,看代码:
与上个版本比较其他都不变,将afnTest2替换下afnTest1方法即可
代码:
- (void)afnTest2{
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_async(group, queue, ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSString *urlString1 = @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3495161387,2602242859&fm=23&gp=0.jpg";
[self AFNRequestWithUrlString:urlString1 message:@"dispatch_group_enter请求1" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求1, json = %@",json);
NSLog(@"最终成功完成了请求1");
//请求成功发送信号量(+1)
dispatch_semaphore_signal(semaphore);
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求1,error = %@",error);
//失败也请求成功发送信号量(+1)
dispatch_semaphore_signal(semaphore);
}];
//信号量减1,如果>0,则向下执行,否则等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSString *urlString2 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=979daec634bebdcbb3c14792a2f1fe83&imgtype=0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F121209%2F234928-12120Z0543764.jpg";
[self AFNRequestWithUrlString:urlString2 message:@"dispatch_group_enter请求2" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求2, json = %@",json);
NSLog(@"最终成功完成了请求2");
dispatch_semaphore_signal(semaphore);
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求2,error = %@",error);
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSString *urlString3 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=76092dbeceb09618622fd7993510c9fb&imgtype=0&src=http%3A%2F%2Fmvimg1.meitudata.com%2F55e2b8683d7464031.jpg";
[self AFNRequestWithUrlString:urlString3 message:@"dispatch_group_enter请求3" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求3, json = %@",json);
NSLog(@"最终成功完成了请求3");
dispatch_semaphore_signal(semaphore);
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求3,error = %@",error);
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSString *urlString4 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=dd23514c28fc192b9aff3b5d0fc79392&imgtype=0&src=http%3A%2F%2Fscimg.jb51.net%2Fallimg%2F160403%2F13-1604032125201L.jpg";
[self AFNRequestWithUrlString:urlString4 message:@"dispatch_group_enter请求4" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求4, json = %@",json);
NSLog(@"最终成功完成了请求4");
dispatch_semaphore_signal(semaphore);
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求4,error = %@",error);
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSString *urlString5 = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=3edc9455c16e8aab5c2ca3d3852104e5&imgtype=0&src=http%3A%2F%2Fmvimg2.meitudata.com%2F5561a1904d4424767.jpg";
[self AFNRequestWithUrlString:urlString5 message:@"dispatch_group_enter请求5" withSuccessBlock:^(id json){
//NSLog(@"最终成功完成了请求5, json = %@",json);
NSLog(@"最终成功完成了请求5");
dispatch_semaphore_signal(semaphore);
} errorBlock:^(NSError *error){
NSLog(@"最终失败完成了请求5,error = %@",error);
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
// 当所有队列执行完成之后
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//返回主线程刷新
NSLog(@"主线程刷新UI");
});
}
效果:
六、NSOperation依赖
1>普通的依赖设置:
代码如下:
#import "ViewController.h"
#import <AFNetworking.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self addBtn1];
}
- (void)addBtn1{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 100, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"普通依赖" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn1) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn1{
[self NormalDependenceOperationQueueWithBlock:^{
NSLog(@"正在刷新!");
}];
}
- (void)NormalDependenceOperationQueueWithBlock:(void(^)())block{
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue setMaxConcurrentOperationCount:4];
NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片...");
}];
[queue addOperation:blockOp1];
NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"实际下载图片");
}];
[blockOp2 addDependency:blockOp1];
[queue addOperation:blockOp2];
NSBlockOperation *blocOpMain = [NSBlockOperation blockOperationWithBlock:^{
block();
}];
[blocOpMain addDependency:blockOp2];
[[NSOperationQueue mainQueue]addOperation:blocOpMain];
}
效果:符合预期效果,有序的执行,看下截图:
2>加AFN的:
代码如下:
#import "ViewController.h"
#import <AFNetworking.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self addBtn1];
[self addBtn2];
}
- (void)addBtn2{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 200, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"AFN依赖" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn2) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn2{
[self afnDependenceOperationQueueWithBlock1:^{
NSLog(@"我正在刷新!");
}];
}
- (void)afnDependenceOperationQueueWithBlock1:(void(^)())block{
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue setMaxConcurrentOperationCount:4];
NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片11111...");
NSString *urlString = @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3495161387,2602242859&fm=23&gp=0.jpg";
[self getWithMessage:@"11111" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了11111");
} failure:^(NSError *error) {
NSLog(@"请求失败了11111");
}];
}];
NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片22222...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=979daec634bebdcbb3c14792a2f1fe83&imgtype=0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F121209%2F234928-12120Z0543764.jpg";
[self getWithMessage:@"22222" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了22222");
} failure:^(NSError *error) {
NSLog(@"请求失败了22222");
}];
}];
NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片33333...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=76092dbeceb09618622fd7993510c9fb&imgtype=0&src=http%3A%2F%2Fmvimg1.meitudata.com%2F55e2b8683d7464031.jpg";
[self getWithMessage:@"33333" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了33333");
} failure:^(NSError *error) {
NSLog(@"请求失败了33333");
}];
}];
NSBlockOperation *blockOp4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片44444...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=dd23514c28fc192b9aff3b5d0fc79392&imgtype=0&src=http%3A%2F%2Fscimg.jb51.net%2Fallimg%2F160403%2F13-1604032125201L.jpg";
[self getWithMessage:@"44444" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了44444");
} failure:^(NSError *error) {
NSLog(@"请求失败了44444");
}];
}];
NSBlockOperation *blockOp5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片55555...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=3edc9455c16e8aab5c2ca3d3852104e5&imgtype=0&src=http%3A%2F%2Fmvimg2.meitudata.com%2F5561a1904d4424767.jpg";
[self getWithMessage:@"55555" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了55555");
} failure:^(NSError *error) {
NSLog(@"请求失败了55555");
}];
}];
[blockOp2 addDependency:blockOp1];
[blockOp3 addDependency:blockOp2];
[blockOp4 addDependency:blockOp3];
[blockOp5 addDependency:blockOp4];
[queue addOperations:@[blockOp1,blockOp2,blockOp3,blockOp4,blockOp5] waitUntilFinished:YES];
NSBlockOperation *blocOpMain = [NSBlockOperation blockOperationWithBlock:^{
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=3edc9455c16e8aab5c2ca3d3852104e5&imgtype=0&src=http%3A%2F%2Fmvimg2.meitudata.com%2F5561a1904d4424767.jpg";
[self getWithMessage:@"66666" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了66666");
block();
} failure:^(NSError *error) {
NSLog(@"请求失败了66666");
}];
}];
[blocOpMain addDependency:blockOp5];
[[NSOperationQueue mainQueue]addOperation:blocOpMain];
}
- (void)getWithMessage:(NSString *)message WithUrlString:(NSString *)urlSting success:(void(^)(id response))success failure:(void(^)(NSError *error))failure{
[self get:urlSting params:nil success:^(id response) {
NSLog(@"%@",message);
success(response);
} failure:^(NSError *error) {
NSLog(@"%@",message);
NSLog(@"%@",error);
failure(error);
}];
}
- (void)get:(NSString *)url
params:(NSDictionary *)params
success:(void(^)(id json))success
failure:(void(^)(NSError *error))failure
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",@"text/plain",@"image/jpeg", nil];
//2发送请求
[manager GET:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) failure(error);
}];
}
@end
效果:这不是我们想要的结果,截图如下:
3>这个时候大家可能会说把manager换成全局变量,代码如下:
#import "ViewController.h"
#import <AFNetworking.h>
@interface ViewController ()
@property(nonatomic, strong) AFHTTPSessionManager *manager;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",@"text/plain",@"image/jpeg", nil];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
_manager = manager;
[self addBtn1];
[self addBtn2];
}
- (void)addBtn2{
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0, 200, 200, 50);
CGPoint btnCenter = CGPointMake(self.view.center.x, btn.frame.origin.y + 25);
btn.center = btnCenter;
btn.backgroundColor = [UIColor orangeColor];
[self.view addSubview:btn];
[btn setTitle:@"AFN依赖" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(didClickBtn2) forControlEvents:UIControlEventTouchUpInside];
}
- (void)didClickBtn2{
[self afnDependenceOperationQueueWithBlock1:^{
NSLog(@"我正在刷新!");
}];
}
- (void)afnDependenceOperationQueueWithBlock1:(void(^)())block{
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue setMaxConcurrentOperationCount:4];
NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片11111...");
NSString *urlString = @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3495161387,2602242859&fm=23&gp=0.jpg";
[self getWithMessage:@"11111" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了11111");
} failure:^(NSError *error) {
NSLog(@"请求失败了11111");
}];
}];
NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片22222...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=979daec634bebdcbb3c14792a2f1fe83&imgtype=0&src=http%3A%2F%2Fimg.taopic.com%2Fuploads%2Fallimg%2F121209%2F234928-12120Z0543764.jpg";
[self getWithMessage:@"22222" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了22222");
} failure:^(NSError *error) {
NSLog(@"请求失败了22222");
}];
}];
NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片33333...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=76092dbeceb09618622fd7993510c9fb&imgtype=0&src=http%3A%2F%2Fmvimg1.meitudata.com%2F55e2b8683d7464031.jpg";
[self getWithMessage:@"33333" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了33333");
} failure:^(NSError *error) {
NSLog(@"请求失败了33333");
}];
}];
NSBlockOperation *blockOp4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片44444...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=dd23514c28fc192b9aff3b5d0fc79392&imgtype=0&src=http%3A%2F%2Fscimg.jb51.net%2Fallimg%2F160403%2F13-1604032125201L.jpg";
[self getWithMessage:@"44444" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了44444");
} failure:^(NSError *error) {
NSLog(@"请求失败了44444");
}];
}];
NSBlockOperation *blockOp5 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"正在开始下载图片55555...");
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=3edc9455c16e8aab5c2ca3d3852104e5&imgtype=0&src=http%3A%2F%2Fmvimg2.meitudata.com%2F5561a1904d4424767.jpg";
[self getWithMessage:@"55555" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了55555");
} failure:^(NSError *error) {
NSLog(@"请求失败了55555");
}];
}];
[blockOp2 addDependency:blockOp1];
[blockOp3 addDependency:blockOp2];
[blockOp4 addDependency:blockOp3];
[blockOp5 addDependency:blockOp4];
[queue addOperations:@[blockOp1,blockOp2,blockOp3,blockOp4,blockOp5] waitUntilFinished:YES];
NSBlockOperation *blocOpMain = [NSBlockOperation blockOperationWithBlock:^{
NSString *urlString = @"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493299941944&di=3edc9455c16e8aab5c2ca3d3852104e5&imgtype=0&src=http%3A%2F%2Fmvimg2.meitudata.com%2F5561a1904d4424767.jpg";
[self getWithMessage:@"66666" WithUrlString:urlString success:^(id response) {
NSLog(@"请求成功了66666");
block();
} failure:^(NSError *error) {
NSLog(@"请求失败了66666");
}];
}];
[blocOpMain addDependency:blockOp5];
[[NSOperationQueue mainQueue]addOperation:blocOpMain];
}
- (void)getWithMessage:(NSString *)message WithUrlString:(NSString *)urlSting success:(void(^)(id response))success failure:(void(^)(NSError *error))failure{
[self get:urlSting params:nil success:^(id response) {
NSLog(@"%@",message);
success(response);
} failure:^(NSError *error) {
NSLog(@"%@",message);
NSLog(@"%@",error);
failure(error);
}];
}
- (void)get:(NSString *)url
params:(NSDictionary *)params
success:(void(^)(id json))success
failure:(void(^)(NSError *error))failure
{
[_manager GET:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) failure(error);
}];
}
@end
效果:貌似好像也算达到了需求,即响应是按序的,但是并不是等到第一个请求响应结束之后再请求其他的,所以严格来说并未达到刚需,另外还有一个问题,一旦5个任务当中有一个耗时操作就不行了,截图如下:
4>那么还是按照GCD中第四点的写法,加信号量,也不必要全局的manager,至于怎么加信号量大家经过GCD第四点的做法肯定知道加了,这里就不贴代码了,有问题评论@我...
七、总结
经过上面的探讨发现如果想要实现每一个AFN请求都在上一个请求响应完成之后再次接着请求目前只有一种解决办法就是GCD的最后一种了,这个可能还会有其他的实现方式,希望有其他方式的大神指教。
Demo后期奉上!希望大家多多支持!