AFNetworking2.0使用心得

這段時間要將公司項目中的網絡引擎由ASIHTTPRequest替換為AFNetworking,替換的過程比較曲折,在此記錄下自己替換過程中得心得:

1、建立數據請求中介者

建立中介者是指項目中的數據請求都通過它去實現,而不是每一個數據請求都直接與AFNetworking打交道,這樣做的好處是:

  • 將網絡請求與第三方庫依賴隔離開來,方便以后對第三方庫的替換。
  • 方便處理網絡請求的公共邏輯。

2、使用completionQueue

默認情況下AFURLConnectionOperation或者AFHTTPRequestOperation請求結束以后會在主線程將結果傳遞回來,如果你要將請求的結果做一些耗時的復雜的處理,就會block住主線程,所以這種情況下你就需要對請求的Operation傳遞completionQueue參數:

AFHTTPRequestOperation *request = [[AFHTTPRequestOperation alloc] initWithRequest:urlrequest];

request.responseSerializer = [AFJSONResponseSerializer serializer];
//設置回調的queue,默認是在mainQueue執行block回調
request.completionQueue = your_request_operation_completion_queue();
[request setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
         //設置了'completionQueue'后,就可以在這里處理復雜的邏輯
         //不用擔心block住了主線程
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

 }];
 [request start];

3、如何知道AFHTTPRequestOperationManager執行完成

開始以為直接設置AFHTTPRequestOperationManagercompletionGroup,然后利用dispatch_group_notify來獲取operationQueue執行結束的通知,最后才發現,這樣根本不行,看了源碼才知道:AFHTTPRequestOperationManager直接將completionGroup賦值給了他的每一個operation,在operation的completionBlock里面利用completionGroup,來確保在operation的處理完成后,將completionBlock置為nil,防止循環引用。

雖然說這樣不能知道AFHTTPRequestOperationManager什么時候執行完成,但是生活還得繼續下去??!在AFURLConnectionOperation中有一個方法叫:

+ (NSArray *)batchOfRequestOperations:(NSArray *)operations
                        progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock
                      completionBlock:(void (^)(NSArray *operations))completionBlock;

這個方法就是能夠發一組請求,跟AFHTTPRequestOperationManager比起來的缺點就是沒法設置并發數,但是它卻能實現檢測一組請求什么時候結束,能檢測完成了多少請求,它是怎么做到的呢?

原來他也是利用dispatch_group_asyncdispatch_group_notify

一般的我們要把一個任務加入一個group里是這樣:

dispatch_group_async(group, queue, ^{
    block();
});

這個寫法等價于

dispatch_async(queue, ^{
    dispatch_group_enter(group);
    block()
    dispatch_group_leave(group);
});

如果要把一個異步任務加入group,這樣就行不通了:

dispatch_group_async(group, queue, ^{
    [self performBlock:^(){
        block();
    }];
    //未執行到block() group任務就已經完成了
});

這是就需要用到batchOfRequestOperations里的實現了:

dispatch_group_enter(group);
[self performBlock:^(){
    block();
    dispatch_group_leave(group);
}];

其實這個和引用計數差不多,dispatch_group_enter時引用計數+1,dispatch_group_leave時引用計數-1,引用計數為0時執行dispatch_group_notify的內容。具體過程大致如下:

AFHTTPRequestOperationManager *downloadManager = [AFHTTPRequestOperationManager manager];
    //設置最大并發數
    [downloadManager.operationQueue setMaxConcurrentOperationCount:([NSProcessInfo processInfo].processorCount) * 2];
    //創建一個group
    __block dispatch_group_t group = dispatch_group_create();
    for (NSURL *url in urlArray) {
        NSURLRequest *requestUrl = [NSURLRequest requestWithURL:url];
        AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:requestUrl];
        [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            dispatch_group_leave(group);
            
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            dispatch_group_leave(group);
            
        }];
        //將請求加入隊列中
        [downloadManager.operationQueue addOperation:requestOperation];
        dispatch_group_enter(group);
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        //全部請求完成
        
    });  

4、實現斷點續傳

AFNetworking雖然支持文件下載的暫停和繼續,但是當緩存清空重新啟動時,它并沒有記錄下下載的狀態,無法續傳,但是可以通過AFDownloadRequestOperation來簡單的實現,其實過程也不是很復雜,大致如下,感興趣的朋友可以閱讀AFDownloadRequestOperation是實現部分:

1、設置AFHTTPRequestOperation的請求NSMutableURLRequestHTTPHeaderRange字段。

NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy];
//offset是指斷點續傳文件已經下載的大小
[mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];

2、設置AFHTTPRequestOperationoutputStream屬性。

//downloadPath是指文件下載存放的路徑
downloadOperation.outputStream = [NSOutputStream outputStreamToFileAtPath:downloadPath append:YES];

結尾

對于ASIHTTPRequestAFNetworking的比較網上有很多很好的文章,一搜一大把,對于普通的使用來說感覺區別不大,請求速度什么的也沒什么感覺,以上若有錯誤,還望大家多多
指正??。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一. 重點: 1.dispatch_queue_create(生成Dispatch Queue) 2.Main D...
    BestJoker閱讀 1,596評論 2 2
  • OC的理解與特性 OC作為一門面向對象的語言,自然具有面向對象的語言特性:封裝、繼承、多態。它既具有靜態語言的特性...
    JW_T閱讀 488評論 0 1
  • 最近看AFNetworking2的源碼,學習這個知名網絡框架的實現,順便梳理寫下文章。AFNetworking2的...
    RobinYu閱讀 301評論 0 0
  • 每一座喧囂的城市里都有高山之上的寂僧。每一條斑斕的街頭都有紅塵之外的人路過。不想打擾你的春暖花開,只想同你一道牧馬...
    良爾傳媒閱讀 509評論 3 2
  • 要比他哭的大聲 讓他知道 哭並不難而且誰都會 讓他看見 哭只是笑話一場 眼淚加上鼻涕 加上可笑的表情 當然更少不了...
    蔡振源閱讀 155評論 2 1