詳解iOS AFNetworking取消正在進(jìn)行的網(wǎng)絡(luò)請(qǐng)求
簡(jiǎn)介
項(xiàng)目開(kāi)發(fā)時(shí),開(kāi)發(fā)人員經(jīng)常會(huì)遇到一種情況,A控制器push進(jìn)入B控制器,B控制器正在進(jìn)行網(wǎng)絡(luò)請(qǐng)求,請(qǐng)求未結(jié)束時(shí),點(diǎn)擊返回回到A控制器,現(xiàn)在問(wèn)題出現(xiàn)了,B中網(wǎng)絡(luò)請(qǐng)求還在執(zhí)行,dealloc并未立即調(diào)用,為什么會(huì)發(fā)生這種情況?想在退出當(dāng)前控制器時(shí)取消掉正在進(jìn)行的請(qǐng)求,怎么做?
網(wǎng)絡(luò)請(qǐng)求的封裝
以AFNetworking為例,上我自己的網(wǎng)絡(luò)請(qǐng)求封裝主要代碼:
//單例模式 + (HttpManager *)sharedManager { static dispatch_once_t once; dispatch_once(&once, ^{ httpManager = [[HttpManager alloc] init]; }); return httpManager; } //網(wǎng)絡(luò)類(lèi)初始化 - (id)init{ self = [super init]; if(self) { manager = [AFHTTPSessionManager manager]; manager.requestSerializer = [AFJSONRequestSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; } return self; }
注意既然封裝為單例,manager在項(xiàng)目運(yùn)行期間就只用初始化一次,所以我把它聲明為了一個(gè)成員變量?,F(xiàn)在來(lái)看看我的網(wǎng)絡(luò)請(qǐng)求調(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) { }];
相信大部分開(kāi)發(fā)者的封裝格式都是類(lèi)似的,個(gè)別反人類(lèi)的封裝格式我也沒(méi)遇到過(guò)。當(dāng)我在B調(diào)用網(wǎng)絡(luò)請(qǐng)求時(shí),突然返回到A(此時(shí)B中請(qǐng)求還在執(zhí)行),但是B中dealloc方法并未立即調(diào)用,等過(guò)幾秒種后,B中請(qǐng)求的數(shù)據(jù)返回了,然后dealloc才調(diào)用。相信很多同學(xué)都遇到過(guò)這種情況,有人會(huì)想是否是block里面有對(duì)象產(chǎn)生了循環(huán)引用,才發(fā)生這種情況。我想說(shuō)的是,如果真是循環(huán)引用,那就會(huì)導(dǎo)致控制器的dealloc方法一直不調(diào)用,而不是上述情況。
在我看來(lái),應(yīng)該是使用了這種Block格式發(fā)起的網(wǎng)絡(luò)請(qǐng)求后,由于還在執(zhí)行,block里面并未得到響應(yīng),所以該block對(duì)當(dāng)前的控制器,有一種強(qiáng)引用的效果,導(dǎo)致控制器退出后,并未釋放掉,直到請(qǐng)求數(shù)據(jù)返回,block里面得到響應(yīng),才算完成,最終調(diào)用dealloc方法。
當(dāng)然,這只是我的見(jiàn)解,有不對(duì)的地方請(qǐng)指出來(lái)。
取消正在進(jìn)行的網(wǎng)絡(luò)請(qǐng)求
上面講了一大堆廢話,現(xiàn)在來(lái)講正題了。由于上述情況的原因,導(dǎo)致我們開(kāi)發(fā)的app在一些非常規(guī)操作上,會(huì)產(chǎn)生一些不友好的效果。現(xiàn)在要求就是在退出控制器B后,取消還在B中進(jìn)行的網(wǎng)絡(luò)請(qǐng)求。
要求清晰了,那么要怎么實(shí)現(xiàn),其實(shí)很簡(jiǎn)單,貼上我的代碼:
- (void)cancelRequest { if ([manager.tasks count] > 0) { NSLog(@"返回時(shí)取消網(wǎng)絡(luò)請(qǐng)求"); [manager.tasks makeObjectsPerformSelector:@selector(cancel)]; //NSLog(@"tasks = %@",manager.tasks); } }
不要每次請(qǐng)求的時(shí)候都去初始化manager(AFHTTPSessionManager)對(duì)象,tasks里面裝的就是正在進(jìn)行的網(wǎng)絡(luò)請(qǐng)求,來(lái)一張圖就理解了:
manager里面的tasks裝的就是正在執(zhí)行的網(wǎng)絡(luò)請(qǐng)求。執(zhí)行cancel后,tasks就會(huì)清空,網(wǎng)絡(luò)請(qǐng)求會(huì)進(jìn)入失敗的狀態(tài),然后響應(yīng)failure block,得到一個(gè)error的信息,表示請(qǐng)求已經(jīng)成功取消了。
至于后臺(tái)服務(wù)器是否會(huì)因?yàn)橹袛嗾?qǐng)求受影響,空閑的同學(xué)可以去測(cè)試下。
最后
還有一些其它取消請(qǐng)求的方法,就不列出來(lái)了,因?yàn)橐痪蜎](méi)成功,要不就很麻煩,在這就用了一種我認(rèn)為最簡(jiǎn)單的方法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- iOS實(shí)現(xiàn)實(shí)時(shí)檢測(cè)網(wǎng)絡(luò)狀態(tài)的示例代碼
- iOS 檢測(cè)網(wǎng)絡(luò)狀態(tài)的兩種方法
- iOS實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài)的改變
- iOS中如何判斷當(dāng)前網(wǎng)絡(luò)環(huán)境是2G/3G/4G/5G/WiFi
- iOS 12+ 中檢測(cè)網(wǎng)絡(luò)訪問(wèn)的方法
- iOS中從網(wǎng)絡(luò)獲取數(shù)據(jù)的幾種方法的比較
- iOS中多網(wǎng)絡(luò)請(qǐng)求的線程安全詳解
- iOS 本地視頻和網(wǎng)絡(luò)視頻流播放實(shí)例代碼
- 詳解IOS判斷當(dāng)前網(wǎng)絡(luò)狀態(tài)的三種方法
相關(guān)文章
IOS UI學(xué)習(xí)教程之使用UIImageView控件制作動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了IOS UI學(xué)習(xí)教程之使用UIImageView控件制作動(dòng)畫(huà),感興趣的小伙伴們可以參考一下2016-03-03iOS App使用SQLite之句柄的定義及數(shù)據(jù)庫(kù)的基本操作
SQLite中在定義過(guò)句柄之后就可以指向數(shù)據(jù)庫(kù),從而利用iOS應(yīng)用程序進(jìn)行打開(kāi)或關(guān)閉等各種操作,這里我們就來(lái)看一下iOS App使用SQLite之句柄的定義及數(shù)據(jù)庫(kù)的基本操作2016-06-06詳解 objective-c中interface與protocol的作用
這篇文章主要介紹了詳解 objective-c中interface與protocol的作用的相關(guān)資料,需要的朋友可以參考下2017-05-05IOS開(kāi)發(fā)網(wǎng)絡(luò)篇—Socket編程詳解
這篇文章主要介紹了IOS開(kāi)發(fā)網(wǎng)絡(luò)篇—Socket編程的相關(guān)資料,需要的朋友可以參考下2016-09-09詳解iOS之關(guān)于double/float數(shù)據(jù)計(jì)算精度問(wèn)題
本篇文章主要介紹了iOS之關(guān)于double/float數(shù)據(jù)計(jì)算精度問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02iOS中UIWebView網(wǎng)頁(yè)加載組件的基礎(chǔ)及使用技巧實(shí)例
UIWebView是開(kāi)發(fā)中很常用的應(yīng)用內(nèi)調(diào)用網(wǎng)頁(yè)瀏覽的控件,這里整理了一些iOS中UIWebView網(wǎng)頁(yè)加載組件的基礎(chǔ)及使用技巧實(shí)例 ,需要的朋友可以參考下2016-06-06IOS如何替換電話號(hào)碼中間4位為"-"符號(hào)
這篇文章主要為大家詳細(xì)介紹了IOS如何替換電話號(hào)碼中間4位為-符號(hào)的方法,感興趣的小伙伴們可以參考一下2016-07-07深入理解Objective-C中類(lèi)的數(shù)據(jù)結(jié)構(gòu)
最近發(fā)現(xiàn)用Objective-C確實(shí)好容易,下面這篇文章主要給大家介紹了關(guān)于Objective-C中類(lèi)的數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05