ios - 异步请求数据,如何快速多次调用接口
巴扎黑
巴扎黑 2017-04-17 14:29:47
[iOS讨论组]

请求同一个接口的数据,我现在是第一个请求成功后请求下一个,有没有其他更快的方法呢?网上说可以自定义几个串行队列,并发执行?求方法。谢谢

接口:


-(void)requestfilterData:(NSString *)item { NSString *urlStr = [NSString stringWithFormat:@"%@/api/product/filter/list?filtername=%@" ,SERVER_ADDRESS,item]; NSURL *url = [NSURL URLWithString:urlStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60]; [request setHTTPMethod:@"GET"]; [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if (connectionError) { NSLog(@" good commet list recv data error"); }else { [self receivedfilterConditionsReturnJSON:data]; } }]; } -(void)receivedfilterConditionsReturnJSON:(NSData *)data { NSError *localError = nil; id parsedObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&localError]; if (localError != nil) { NSLog(@"sport train filter list JSON data error: %@", [localError description]); return; } NSDictionary *recvDic = (NSDictionary *)parsedObject; //接收商品评论数据 NSString *result = [recvDic objectForKey:@"result"]; if ([result isEqualToString:@"1"]) { dispatch_async(dispatch_get_main_queue(), ^{ [self showItemController:recvDic]; }); } }

需求:实在页面出现的时候,要根据参数分三次调用这个接口(服务端就是这么设计的,并不是一次返回了)。

巴扎黑
巴扎黑

全部回复(4)
阿神

谢邀。第一次被邀请 必须好好回答。

建议阅读同步与异步

看了下您的问题,但是总觉得你对同步和异步的理解有差(可能是我看错了),但是我建议首先阅读下这篇文章

  • NSURLConnection的使用

虽然讲的是如何使用,但是作者很好的诠释了同步和异步的区别,也有实际例子来阐述两者。

建议阅读-NSOperationQueue

有了同步与异步,那么解决这个问题还需要多线程和队列的知识,阅读下下面的链接

使用NSOperationQueue简化多线程开发和队列的优先级

楼主的问题解析

楼主可否思考下,如何将上面的两者结合下,运用于自己的程序中?

  • 思路一:直接多线程执行...

这里我们使用上面我提到的[NSURLConnection的使用]的代码为例子,github地址:code source 请自己下载下来

//ViewController.m中的viewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];

  //  [self fetchAppleHtml];
//    [self fetchYahooData];
//    [self fetchYahooData];
    [self fetchYahooData2_GCD];
    [self fetchYahooData2_GCD];//连续两次运行试一下,看下打印的信息
//    [self httpGetWithParams];
}

  • 思路二:队列执行网络层...

与第一种差不多,但是是在网络请求内容执行队列

备注

写了那么多,不知道是不是回答道重点上了。
我没有亲自试,所以题主测试下,我可能理解有偏差,见谅。

大家讲道理

可不可以解释一下,你为什么要对这三次请求与响应做同步处理?
一个请求的发出依赖另一个跟它同类请求的响应,会造成这种情况,给人第一感觉是设计有问题啊。
我没看懂你的问题,只能凭直觉猜测一下你想干什么。我的直觉是你只是想在回调方法里知道请求是谁发的。。。我猜我是理解错了。。不能是这么简单的问题吧。。
有人看懂问题了吗?
顺便建议用NSURLSession代替NSURLConnection,如果不需要兼容7.0之前的设备的话。

-(void)requestfilterData:(NSString *)item requestCode:(int)requestCode
{
    NSString *urlStr = [NSString stringWithFormat:@"%@/api/product/filter/list?filtername=%@" ,SERVER_ADDRESS,item];
    NSURL *url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];

    [request setHTTPMethod:@"GET"];

    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (connectionError) {
            NSLog(@" good commet list recv data error");
        }else
        {
            [self receivedfilterConditionsReturnJSON:data requestCode:requestCode];
        }
    }];
}

-(void)receivedfilterConditionsReturnJSON:(NSData *)data requestCode:(int)requestCode
{
    NSError *localError = nil;

    id parsedObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&localError];
    if (localError != nil) {

        NSLog(@"sport train filter list  JSON data error: %@", [localError description]);
        return;
    }

    NSDictionary *recvDic = (NSDictionary *)parsedObject;
    //接收商品评论数据
    NSString *result =  [recvDic objectForKey:@"result"];

    if ([result isEqualToString:@"1"]) {

        switch(requestCode)
        {
            case REQUEST_0:
            {
                //...
                break;
            }
            case REQUEST_1:
            //...
        }
    }
}
怪我咯

想了好久还是使用了dispatch_group_t,多路执行后收到通知再执行UI操作,然后,调用的接口我改成了同步请求,(异步也可以吧,需要在创建一个NSOperationQueue)本身dispatch_get_global_queue就是异步了,在开一个感觉没必要)

dispatch_group_t group =  dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

    //1
      [self requestfilterData:@"location"];
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

    //2
     [self requestfilterData:@"age"];
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
    //3
    [self requestfilterData:@"item"];
});

dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
   //汇总结果

    dispatch_async(dispatch_get_main_queue(), ^{

       //UI操作

    });
});

//同步请求数据

-(void)requestfilterData:(NSString *)item
{
    NSString *urlStr = [NSString stringWithFormat:@"%@/api/product/filter/list?type=%ld&filtername=%@" ,SERVER_ADDRESS, (long) self.type, item];
    NSURL *url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];

    [request setHTTPMethod:@"GET"];
    NSURLResponse *response = nil;
    NSError *error = nil;

   NSData *data =[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if (error) {
         NSLog(@" good commet list recv data error");
    }else
    {
         [self receivedfilterConditionsReturnJSON:data withCode:item];
    }
}
伊谢尔伦

自己实现一个队列管理,完成之后在进行下一个。如果要精确控制的话,可以看看asi框架的 queue代码。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号