AFNetworking使用過程中的幾個細節
阿新 • • 發佈:2019-01-25
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];
}];