IOS開發筆記_AFN中多線程依賴
我們平常在開發當中很可能會遇到同時開啟兩個網路請求,然後把資源下載下來後進行合併作業,那麼在AFN中我們究竟要怎麼做呢,當然,以下可能寫出一些個人的封裝技巧,有興趣的朋友可以發繼續關注我。
#pragma mark - getter
- (NSOperationQueue *)queue
{
if (!_queue) {
_queue = [[NSOperationQueuealloc]init];
}
return_queue;
}
這裡是我個人對AFN的一個封裝類,後面會說到
NSOperationQueue *mainQueue = [NSOperationQueuemainQueue];
//建立網路請求對象
RequestManager *manager = [RequestManagermanager];
這裡同樣對請求參數進行了封裝,因為在開發過程中,一條請求可能帶有許多公用參數,例如UID,DID,APPVersion ,螢幕解析度,系統操作版本等等參數,如果每次都寫一遍豈不是累死人,那麼,肯定要用到繼承父類了,只有父類都有到這些參數,他的子類也肯定帶上了
// 配置請求參數
FSDynamicParams *dynamicParams = [[FSDynamicParamsalloc]initWithDynamicListParamsWithCityId:@2page:self.page];
// 這裡對的AFHTTPRequestOperation請求進行了封裝,目的是讓代碼更加簡潔
AFHTTPRequestOperation *operationList = [manageroperationGETWithParams:dynamicParamsToController:selfSuccessHandle:^(id responseObject) {
FSLog(@第一步);
}];
//配置請求參數
FSDynamicParams *messageParams = [[FSDynamicParamsalloc]initWithDynamicMessageParams];
// 這裡對的AFHTTPRequestOperation請求進行了封裝,目的是讓代碼更加簡潔
AFHTTPRequestOperation *operationMessage = [manageroperationGETWithParams:messageParamsToController:selfSuccessHandle:^(id responseObject) {
FSLog(@第二步);
}];
NSBlockOperation *operation3 = [NSBlockOperationblockOperationWithBlock:^{
#warning 這裡好奇怪,一定要開一個延時線程才能按正常順序執行,AFN線程的坑真是多,記錄一下
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
FSLog(@第三步);
});
}];
[operation3addDependency:operationList];
[operation3addDependency:operationMessage];
[self.queueaddOperation:operationList];
[self.queueaddOperation:operationMessage];
[mainQueueaddOperation:operation3];
這裡先說一下為什麼第三步結果步要開啟一個0.1秒的延時,如果平時示範的話是沒必要開的,但是當你在第二步操作裡面執行的操作比較多的時候,問題就發生了,線程就會想傻了一樣第一步、結果步、第三步執行,當然,我也吃了不少虧,最後研究了一下,只得除瞭解決方案,還沒有只得原來,實在只能說莫名其妙,可能是我目前知識還不夠吧,只能Mark一下,以後繼續往裡面看看了。
說一下封裝類的,RequestManager的部分代碼
@class BaseParams;
@class FSBaseViewController;
@interface RequestManager :NSObject
- (AFHTTPRequestOperation *)operationGETWithParams:(BaseParams *)params ToController:(UIViewController *)controller SuccessHandle:(void (^)(id responseObject))SuccessHandle;
@end
@implementation RequestManager
+ (instancetype)manager
{
RequestManager *manager = [[RequestManageralloc]init];
return manager;
}
// 返回線程操作
- (AFHTTPRequestOperation *)operationGETWithParams:(BaseParams *)params ToController:(UIViewController *)controller SuccessHandle:(void (^)(id responseObject))SuccessHandle{
//將字典的參數通過AFN的方法轉化成http結構的字串
NSMutableURLRequest *request = [[AFHTTPRequestSerializerserializer]requestWithMethod:@GETURLString:URL_BASEparameters:[paramskeyValue]error:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperationalloc]initWithRequest:request];
// 設定返回解析器為JSON格式
operation.responseSerializer = [AFJSONResponseSerializerserializer];
// 設定線程操作
[operationsetCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation,id responseObject) {
if ([responseObject[@result]intValue] !=0 ) {
// 這裡是對MBProgressHUD的再封裝,自訂了一個類
[MBProgressHUBhubWithShowText:responseObject[@message]toView:controller.view];
return;
}
FSLog(@success:%@,responseObject);
SuccessHandle(responseObject);
}failure:^(AFHTTPRequestOperation *operation,NSError *error) {
//請求失敗後的統一操作,例如告訴使用者,請求逾時來,,什麼什麼的,傳進來的控制器可以在這裡判斷,改控制器為哪一個時可以做一些顯示不同圖片的操作
//網路請求層,就應該做網路請求的處理嘛,個人是這麼認為了,網路請求任何情況都歸這個類管
if ([controllerisKindOfClass:[FSBaseTableViewControllerclass]]) {
[[(FSBaseTableViewController *)controllertableView].headerendRefreshing];
}
[MBProgressHUBhubWithShowStatusCode:NetWorkNotRechabilytoView:controller.view];
FSLog(@failure:request --- %@,operation.request);
}];
return operation;
}
覺得以上代碼還對你有用的小夥伴記得支援我喔,好了,Mark做完了,繼續敲代碼去