詳解iOS AFNetworking取消正在進行的網(wǎng)絡(luò)請求
簡介
項目開發(fā)時,開發(fā)人員經(jīng)常會遇到一種情況,A控制器push進入B控制器,B控制器正在進行網(wǎng)絡(luò)請求,請求未結(jié)束時,點擊返回回到A控制器,現(xiàn)在問題出現(xiàn)了,B中網(wǎng)絡(luò)請求還在執(zhí)行,dealloc并未立即調(diào)用,為什么會發(fā)生這種情況?想在退出當前控制器時取消掉正在進行的請求,怎么做?
網(wǎng)絡(luò)請求的封裝
以AFNetworking為例,上我自己的網(wǎng)絡(luò)請求封裝主要代碼:
//單例模式
+ (HttpManager *)sharedManager
{
static dispatch_once_t once;
dispatch_once(&once, ^{
httpManager = [[HttpManager alloc] init];
});
return httpManager;
}
//網(wǎng)絡(luò)類初始化
- (id)init{
self = [super init];
if(self)
{
manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
}
return self;
}
注意既然封裝為單例,manager在項目運行期間就只用初始化一次,所以我把它聲明為了一個成員變量。現(xiàn)在來看看我的網(wǎng)絡(luò)請求調(diào)用形式:
[[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調(diào)用網(wǎng)絡(luò)請求時,突然返回到A(此時B中請求還在執(zhí)行),但是B中dealloc方法并未立即調(diào)用,等過幾秒種后,B中請求的數(shù)據(jù)返回了,然后dealloc才調(diào)用。相信很多同學都遇到過這種情況,有人會想是否是block里面有對象產(chǎn)生了循環(huán)引用,才發(fā)生這種情況。我想說的是,如果真是循環(huán)引用,那就會導致控制器的dealloc方法一直不調(diào)用,而不是上述情況。
在我看來,應(yīng)該是使用了這種Block格式發(fā)起的網(wǎng)絡(luò)請求后,由于還在執(zhí)行,block里面并未得到響應(yīng),所以該block對當前的控制器,有一種強引用的效果,導致控制器退出后,并未釋放掉,直到請求數(shù)據(jù)返回,block里面得到響應(yīng),才算完成,最終調(diào)用dealloc方法。
當然,這只是我的見解,有不對的地方請指出來。
取消正在進行的網(wǎng)絡(luò)請求
上面講了一大堆廢話,現(xiàn)在來講正題了。由于上述情況的原因,導致我們開發(fā)的app在一些非常規(guī)操作上,會產(chǎn)生一些不友好的效果?,F(xiàn)在要求就是在退出控制器B后,取消還在B中進行的網(wǎng)絡(luò)請求。
要求清晰了,那么要怎么實現(xiàn),其實很簡單,貼上我的代碼:
- (void)cancelRequest
{
if ([manager.tasks count] > 0) {
NSLog(@"返回時取消網(wǎng)絡(luò)請求");
[manager.tasks makeObjectsPerformSelector:@selector(cancel)];
//NSLog(@"tasks = %@",manager.tasks);
}
}
不要每次請求的時候都去初始化manager(AFHTTPSessionManager)對象,tasks里面裝的就是正在進行的網(wǎng)絡(luò)請求,來一張圖就理解了:

manager里面的tasks裝的就是正在執(zhí)行的網(wǎng)絡(luò)請求。執(zhí)行cancel后,tasks就會清空,網(wǎng)絡(luò)請求會進入失敗的狀態(tài),然后響應(yīng)failure block,得到一個error的信息,表示請求已經(jīng)成功取消了。
至于后臺服務(wù)器是否會因為中斷請求受影響,空閑的同學可以去測試下。
最后
還有一些其它取消請求的方法,就不列出來了,因為要不就沒成功,要不就很麻煩,在這就用了一種我認為最簡單的方法。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- iOS實現(xiàn)實時檢測網(wǎng)絡(luò)狀態(tài)的示例代碼
- iOS 檢測網(wǎng)絡(luò)狀態(tài)的兩種方法
- iOS實時監(jiān)控網(wǎng)絡(luò)狀態(tài)的改變
- iOS中如何判斷當前網(wǎng)絡(luò)環(huán)境是2G/3G/4G/5G/WiFi
- iOS 12+ 中檢測網(wǎng)絡(luò)訪問的方法
- iOS中從網(wǎng)絡(luò)獲取數(shù)據(jù)的幾種方法的比較
- iOS中多網(wǎng)絡(luò)請求的線程安全詳解
- iOS 本地視頻和網(wǎng)絡(luò)視頻流播放實例代碼
- 詳解IOS判斷當前網(wǎng)絡(luò)狀態(tài)的三種方法
相關(guān)文章
深入理解Objective-C中類的數(shù)據(jù)結(jié)構(gòu)
最近發(fā)現(xiàn)用Objective-C確實好容易,下面這篇文章主要給大家介紹了關(guān)于Objective-C中類的數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧2018-05-05
Xcode 下刪除Provisioning Profiles文件詳細介紹
這篇文章主要介紹了Xcode 下刪除Provisioning Profiles文件詳細介紹的相關(guān)資料,需要的朋友可以參考下2016-12-12
iOS開發(fā)TableView網(wǎng)絡(luò)請求及展示預(yù)加載實現(xiàn)示例
這篇文章主要為大家介紹了iOS開發(fā)TableView網(wǎng)絡(luò)請求及展示預(yù)加載實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07
實例講解iOS音樂播放器DOUAudioStreamer用法
本篇文章給大家通過實例講解了iOS音樂播放器DOUAudioStreamer用法以及分享了實例代碼,一起學習參考下吧。2017-12-12
iOS中使用UItableviewcell實現(xiàn)團購和微博界面的示例
這篇文章主要介紹了iOS中使用UItableviewcell實現(xiàn)團購和微博界面的示例,開發(fā)語言基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-01-01

