最近發(fā)現(xiàn)應(yīng)用有卡頓現(xiàn)象眯分,后來(lái)仔細(xì)查找荤胁,發(fā)現(xiàn)有幾個(gè)地方是挺耗內(nèi)存的。
1.應(yīng)用中使用了地圖艺谆,頁(yè)面返回的時(shí)候榨惰,地圖緩存沒有清理
2.網(wǎng)絡(luò)請(qǐng)求,頁(yè)面返回的時(shí)候沒有終止網(wǎng)絡(luò)加載任務(wù)
3.加載的h5頁(yè)面静汤,沒有進(jìn)行緩存琅催,著實(shí)體驗(yàn)不佳,每次都要加載
4.dealloc方法虫给,為什么沒有執(zhí)行藤抡?
5.app中怎樣減少loading,達(dá)到更順暢的體驗(yàn)
針對(duì)以上問題狰右,進(jìn)行了一系列的檢索杰捂,實(shí)驗(yàn),不過慶幸的是棋蚌,差不多一天的時(shí)間嫁佳,把這些問題都解決了,現(xiàn)做一下整理谷暮。
解決問題1.應(yīng)用中使用了地圖蒿往,頁(yè)面返回的時(shí)候,地圖緩存沒有清理
應(yīng)用中使用了地圖湿弦,頁(yè)面返回的時(shí)候瓤漏,地圖緩存沒有清理,項(xiàng)目中集成了蘋果地圖颊埃,發(fā)現(xiàn)每次打開地圖界面蔬充,內(nèi)存都會(huì)上升幾十M,并且一直上升不降班利,直到卡死饥漫,造成這一結(jié)果的根本原因是地圖的mapView沒有釋放,導(dǎo)致每次打開地圖界面的時(shí)候內(nèi)存中都重新加載了一個(gè)地圖mapView罗标。于是在網(wǎng)上搜索了一番找到了解決辦法庸队,只需要在地圖的ViewController中dealloc方法中釋放掉mapView积蜻,將mapView設(shè)置成nil就行了。詳見博客地址:http://blog.csdn.net/isalvador/article/details/51082860彻消,具體代碼如下:
//并且在界面將要顯示的時(shí)候設(shè)置代理竿拆,將要消失的時(shí)候取消代理
- (void)viewWillAppear:(BOOL)animated {
_mapView.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated {
_mapView.delegate = nil;
}
- (void)dealloc{
if (_mapView) {
_mapView = nil;
}
}
備注:如果沒有調(diào)用dealloc方法,請(qǐng)查看問題4的解決方法
解決問題2.網(wǎng)絡(luò)請(qǐng)求宾尚,頁(yè)面返回的時(shí)候沒有終止網(wǎng)絡(luò)加載任務(wù)
根據(jù)簡(jiǎn)書上的文章iOS取消界面的網(wǎng)絡(luò)請(qǐng)求得到的答案:要取消網(wǎng)絡(luò)請(qǐng)求,就需要一個(gè)類NSURLSessionDataTask的對(duì)象方法-cancel丙笋,有時(shí)候一個(gè)頁(yè)面可能有多個(gè)請(qǐng)求,這個(gè)時(shí)候怎么辦呢央勒?對(duì)不见,可以將每個(gè)task放在數(shù)組里澳化,然后在頁(yè)面退出調(diào)用dealloc方法時(shí)崔步,遍歷一下這個(gè)數(shù)組,判斷如果有正在執(zhí)行中的任務(wù)取消掉就可以了缎谷。就是這么簡(jiǎn)單井濒!
// 將請(qǐng)求任務(wù)添加到數(shù)組中,以post方式為例列林,get方式相同
NSURLSessionDataTask *urlTask = [self.httpSessionManager POST:URLString parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
DebugLog(@"====請(qǐng)求成功獲取到的數(shù)據(jù)====%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
DebugLog(@"error ==>%@",error)瑞你;
}];
[self.urlTaskArray addObject:urlTask];
// 然后在這里遍歷數(shù)組,取消掉正在執(zhí)行的任務(wù)
- (void)dealloc{
if (self.urlTaskArray.count) {
for (NSURLSessionDataTask *urlTask in self.urlTaskArray) {
if (urlTask.state == NSURLSessionTaskStateRunning) {
[urlTask cancel];
}
}
}
}
解決問題3.加載的h5頁(yè)面希痴,沒有進(jìn)行緩存者甲,著實(shí)體驗(yàn)不佳,每次都要加載
思路是第一次加載之后進(jìn)行緩存砌创,下次直接從緩存中獲取虏缸,不用再次加載,詳見我的另一篇文章
iOS 緩存之(WebView)網(wǎng)頁(yè)緩存
解決問題4.dealloc方法嫩实,為什么沒有執(zhí)行刽辙?
根本原因是當(dāng)前的控制器的引用計(jì)數(shù)不為1,就是說(shuō)可能存在沒有被釋放的情況甲献,造成了循環(huán)引用宰缤。
可能有這幾種情況:
1>代理屬性是否使用assign進(jìn)行修飾,而不是weak晃洒,assign比weak少了一個(gè)功能慨灭,對(duì)象不用時(shí)不能自動(dòng)設(shè)置成nil。
2>block中是否使self球及,而不是__weak typeof(self) weakSelf = self; 中的weakSelf氧骤,造成了相互持有,都不能釋放掉桶略。
3>遵守的協(xié)議有沒有設(shè)置能nil语淘。
- (void)viewWillAppear:(BOOL)animated {
_mapView.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated {
_mapView.delegate = nil;
}
經(jīng)過鄙人的測(cè)試诲宇,一般就是這幾個(gè)問題造成的,如果還是沒有執(zhí)行dealloc方法惶翻,請(qǐng)反復(fù)進(jìn)行核實(shí)以上步驟姑蓝。
解決5.app中怎樣減少loading,達(dá)到更順暢的體驗(yàn)
情形1>app中有兩個(gè)詳情頁(yè)面需要先加載圖片吕粗,然后在顯示其他內(nèi)容纺荧,而且圖片也是要加載原圖,因?yàn)閳D片質(zhì)量較高颅筋,所以添加了loading宙暇,是的使用了SDWebImage進(jìn)行緩存,但是每次都顯示loading體驗(yàn)不太好议泵。解決方法占贫,每次顯示loaidng前,先進(jìn)行判斷如果有緩存先口,將不顯示loading直接從緩存中取得圖片型奥。獲取SDWebImage緩存的方法
// 因?yàn)檫@個(gè)方法在子線程(全局隊(duì)列)中執(zhí)行,所以不需要考慮死線程的問題
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager diskImageExistsForURL:pathUrl]; // pathUrl 是你要加載圖片的url
if ([manager diskImageExistsForURL:pathUrl]) {
UIImage *image = [[manager imageCache] imageFromDiskCacheForKey:pathUrl.absoluteString];
[self loadSquarePhotoWithImage:image];
}else{
[SVProgressHUD show];
UIImageView *tappedImageView = [[UIImageView alloc]init];
__weak typeof(self) weakSelf = self;
[tappedImageView sd_setImageWithURL:pathUrl placeholderImage:nil options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
tappedImageView.image = image;
[weakSelf loadSquarePhotoWithImage:image];
[SVProgressHUD dismiss];
}];
}
情形2>每次加載h5的時(shí)候,考慮到網(wǎng)絡(luò)情況不穩(wěn)定碉京,網(wǎng)速慢的情況厢汹,添加了loading,但是每次打開都要顯示loading谐宙,都要加載一次烫葬,體驗(yàn)不好。
思路是第一次加載顯示loading凡蜻,加載完成之后進(jìn)行緩存搭综,下次直接從緩存中獲取,不用再次加載咽瓷,也不用在顯示loading了设凹,詳見我的另一篇文章
iOS 緩存之(WebView)網(wǎng)頁(yè)緩存