AFN多请求依赖(一)

AFN之使用问题解析
AFN多请求依赖(二)

一、基本简介

一直想要把自己这几年的相关的工作上遇到的知识点通过文字整理出来,但是一直不想写,不知道是不是一直以来对于作文的恐惧,但最近闲来无事做,正式开始我的码字生涯。笔者:七禾。

二、联系方式

这也是我的第一篇文章,有不对和欠缺的地方望各位大神不吝赐教。个人联系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个任务不是按顺序执行的,是无序的。即效果不达预期。

Snip20170428_4.png

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

效果:

Snip20170428_5.png

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");
    });
}

效果:

Snip20170428_6.png
六、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];
}

效果:符合预期效果,有序的执行,看下截图:

Snip20170429_7.png

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

效果:这不是我们想要的结果,截图如下:

Snip20170429_9.png

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个任务当中有一个耗时操作就不行了,截图如下:

Snip20170429_10.png

4>那么还是按照GCD中第四点的写法,加信号量,也不必要全局的manager,至于怎么加信号量大家经过GCD第四点的做法肯定知道加了,这里就不贴代码了,有问题评论@我...

七、总结

经过上面的探讨发现如果想要实现每一个AFN请求都在上一个请求响应完成之后再次接着请求目前只有一种解决办法就是GCD的最后一种了,这个可能还会有其他的实现方式,希望有其他方式的大神指教。

Demo后期奉上!希望大家多多支持!

AFN之使用问题解析
AFN多请求依赖(二)

小七.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容