詳解iOS AFNetworking取消正在進行的網絡請求
簡介
項目開發(fā)時,開發(fā)人員經常會遇到一種情況,A控制器push進入B控制器,B控制器正在進行網絡請求,請求未結束時,點擊返回回到A控制器,現在問題出現了,B中網絡請求還在執(zhí)行,dealloc并未立即調用,為什么會發(fā)生這種情況?想在退出當前控制器時取消掉正在進行的請求,怎么做?
網絡請求的封裝
以AFNetworking為例,上我自己的網絡請求封裝主要代碼:
//單例模式 + (HttpManager *)sharedManager { static dispatch_once_t once; dispatch_once(&once, ^{ httpManager = [[HttpManager alloc] init]; }); return httpManager; } //網絡類初始化 - (id)init{ self = [super init]; if(self) { manager = [AFHTTPSessionManager manager]; manager.requestSerializer = [AFJSONRequestSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; } return self; }
注意既然封裝為單例,manager在項目運行期間就只用初始化一次,所以我把它聲明為了一個成員變量。現在來看看我的網絡請求調用形式:
[[HttpManager sharedManager] dataFromWithBaseURL:BaseURL path:url method:@"POST" timeInterval:10 params:parmas success:^(NSURLRequest *request, NSURLResponse *response, id JSON) { } failure:^(NSURLRequest *request, NSURLResponse *response, NSError *error, id JSON) { } error:^(id JSON) { } finish:^(id JSON) { }];
相信大部分開發(fā)者的封裝格式都是類似的,個別反人類的封裝格式我也沒遇到過。當我在B調用網絡請求時,突然返回到A(此時B中請求還在執(zhí)行),但是B中dealloc方法并未立即調用,等過幾秒種后,B中請求的數據返回了,然后dealloc才調用。相信很多同學都遇到過這種情況,有人會想是否是block里面有對象產生了循環(huán)引用,才發(fā)生這種情況。我想說的是,如果真是循環(huán)引用,那就會導致控制器的dealloc方法一直不調用,而不是上述情況。
在我看來,應該是使用了這種Block格式發(fā)起的網絡請求后,由于還在執(zhí)行,block里面并未得到響應,所以該block對當前的控制器,有一種強引用的效果,導致控制器退出后,并未釋放掉,直到請求數據返回,block里面得到響應,才算完成,最終調用dealloc方法。
當然,這只是我的見解,有不對的地方請指出來。
取消正在進行的網絡請求
上面講了一大堆廢話,現在來講正題了。由于上述情況的原因,導致我們開發(fā)的app在一些非常規(guī)操作上,會產生一些不友好的效果?,F在要求就是在退出控制器B后,取消還在B中進行的網絡請求。
要求清晰了,那么要怎么實現,其實很簡單,貼上我的代碼:
- (void)cancelRequest { if ([manager.tasks count] > 0) { NSLog(@"返回時取消網絡請求"); [manager.tasks makeObjectsPerformSelector:@selector(cancel)]; //NSLog(@"tasks = %@",manager.tasks); } }
不要每次請求的時候都去初始化manager(AFHTTPSessionManager)對象,tasks里面裝的就是正在進行的網絡請求,來一張圖就理解了:
manager里面的tasks裝的就是正在執(zhí)行的網絡請求。執(zhí)行cancel后,tasks就會清空,網絡請求會進入失敗的狀態(tài),然后響應failure block,得到一個error的信息,表示請求已經成功取消了。
至于后臺服務器是否會因為中斷請求受影響,空閑的同學可以去測試下。
最后
還有一些其它取消請求的方法,就不列出來了,因為要不就沒成功,要不就很麻煩,在這就用了一種我認為最簡單的方法。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
IOS UI學習教程之使用UIImageView控件制作動畫
這篇文章主要為大家詳細介紹了IOS UI學習教程之使用UIImageView控件制作動畫,感興趣的小伙伴們可以參考一下2016-03-03iOS App使用SQLite之句柄的定義及數據庫的基本操作
SQLite中在定義過句柄之后就可以指向數據庫,從而利用iOS應用程序進行打開或關閉等各種操作,這里我們就來看一下iOS App使用SQLite之句柄的定義及數據庫的基本操作2016-06-06詳解 objective-c中interface與protocol的作用
這篇文章主要介紹了詳解 objective-c中interface與protocol的作用的相關資料,需要的朋友可以參考下2017-05-05