AFNetworking使用过程中的几个细节

0.先来看一下AFN如何发送GET请求的

 // 发送网络请求
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"a"] = @"category";
params[@"c"] = @"subscribe";

[[AFHTTPSessionManager manager] GET:@"https://api.3w.com/api/api_open.php" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

}];

1.在实际项目中,我们往往是点击一个按钮就发送了GET请求,但如果因为网请求需要时间,在数据没有还没有返回来,这个时候我退出了当前控制器返回上一级,应该取消AFN的所有操作。
当前控制器销毁会调用dealloc方法,我们可以在这个方法里做取消AFN操作的工作。

那么如何拿到AFN管理者呢?
(1)、用属性保存AFN管理者

/**
 *  AFN请求管理者
 */
@property(nonatomic,strong)AFHTTPSessionManager *manager;
- (AFHTTPSessionManager *)manager
{
    if (!_manager) {
        _manager = [AFHTTPSessionManager manager];
    }
    return _manager;
}

这样我们在GET请求的时候,就应该这样写:

[self.manager GET:@"https://api.3w.com/api/api_open.php" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {


} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

}];

(2)、

#pragma mark - 控制器的销毁
- (void)dealloc
{
    // AFN停止所有操作
    [self.manager.operationQueue cancelAllOperations];
}

2.有的时候我们可以会不停的发送多个请求,但只要最后一次请求返回的数据。
这里写图片描述
比如这个案列中,我们点击左侧分类分别请求网络数据,但其实我们只需要处理当前分类的数据。

如何解决这种需求?
(1)、保存每次请求的参数

/**
 *  请求参数
 */
@property(nonatomic,strong)NSMutableDictionary *params;
// 准备请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"a"] = @"list";
params[@"c"] = @"subscribe";
params[@"category_id"] = @(c.id);
params[@"page"] = @(c.currentPage);
self.params = params; // 保存

(2)、在GET返回中判断属性params和当前请求的参数是否相同,我们只需要处理当前请求的数据。所以参数不同就return。

[self.manager GET:@"https://api.3w.com/api/api_open.php" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

        if (self.params != params) return; //这里判断

        //处理反正数据...(这里是我们想要的当前分类的数据了)

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         if (self.params != params) return; // 这里判断
    }];

3、优化
当用户依次点击『网红、精品、搞笑』这些分类,都要做网络请求,在上面我们是判断了非最后一次请求不处理返回数据,其实这样不好。因为即使前面请求返回来的数据我们将来还是可以用到,比如用户从『搞笑』分类又回到『精品』,所以来修改一下我们上面的代码,把判断是否是最后一次请求的代码放到 服务区返回数据处理完毕和刷新表格之间。
本案例中代码如下:

// 发送请求给服务器,加载右侧的数据
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"list";
    params[@"c"] = @"subscribe";
    params[@"category_id"] = @(c.id);
    params[@"page"] = @(c.currentPage);
    self.params = params;

    [self.manager GET:@"https://api.budejie.com/api/api_open.php" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

        // 字典数组 -> 模型数组
        NSArray *users = [RecommendUser mj_objectArrayWithKeyValuesArray:responseObject[@"list"]];

        // 清除以前所有旧数据
        [c.users removeAllObjects];

        // 添加到当前类别对应的用户数组中
        [c.users addObjectsFromArray:users];

        // 保存从服务器返回数据的总条数
        c.total = [responseObject[@"total"] integerValue];

        // 不是最后一次请求
        if (self.params != params) return;

        // 必须要刷新表格
        [self.userTableView reloadData];

        // 结束刷新
        [self.userTableView.mj_header endRefreshing];
        if (c.users.count == c.total) {
            [self.userTableView.mj_footer endRefreshingWithNoMoreData];
        }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         if (self.params != params) return;

        // 提醒
        [SVProgressHUD showErrorWithStatus:@"加载用户数据失败 "];

        // 结束刷新
        [self.userTableView.mj_header endRefreshing];
    }];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值