美文网首页iOS基本功春天来咯
AFN内存泄漏的2种解决方法和对内存影响对比(附demo)

AFN内存泄漏的2种解决方法和对内存影响对比(附demo)

作者: wg689 | 来源:发表于2019-03-23 15:13 被阅读203次

1) AFN泄漏展示代码

push 一个控制器, 这个 控制器中有一个网络请求.

- (void)requst:(NSString*)url{
    //默认配置
//    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//    //AFN3.0+基于封住URLSession的句柄
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    __weak typeof(manager) weakmanager = manager;
//    __weak typeof(self) weakSelf = self
   // AFURLSessionManager *manager = [AppDelegate sharedManager];
    
    //请求
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    //下载Task操作
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        //- block的返回值, 要求返回一个URL, 返回的这个URL就是文件的位置的路径
        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
        
        
        
        return [NSURL fileURLWithPath:path];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        NSLog(@"错误信息%@",error);
        //设置下载完成操作
        // filePath就是你下载文件的位置,你可以解压,也可以直接拿来使用
        if ([[NSFileManager defaultManager] fileExistsAtPath:[filePath path]]) {
            NSString *zipPath = [filePath path];// 将NSURL转成NSString
        }
//        [weakmanager invalidateSessionCancelingTasks:YES];
    }];
    [downloadTask resume];
}

2) 如何查看内存泄漏(2种方式)

防止干扰 控制器释放, 确保控制器100% 释放 , 重写AFN 所在的控制器的dealloc方法

2.1) 直接看对象的方式
2.1.1)点击xcode
image.png
2.2.2) 看到1000个对象未释放
image.png

通过上述发现AFN 的对象未释放 1000次,就有1000 个manager 相关的对象都没有释放

2.2) instrument 查看

并不是所有的未释放对象都可以instrument 查看

image.png
2.3) 泄漏1000次的内存对比
image.png image.png

1000次 ,相比一次泄漏 内存5.9M , 如果相关的代码更复杂 ,1000次所耗用 的内存只会更多

3) 内存泄漏修改方式

image.png

修改之后


image.png image.png

官方推荐单例
特殊情况不要使用单例

4) 两种解决方法的优缺点

4.1) 取消法的优缺点
  • 优点: 一次泄漏也没有 , 对象释放最彻底
  • 缺点: 改动很麻烦, 每个都需要修改, 如果对AFN 有封装的话, 修改还是比较方便, AFN 没有封装的话, 改动会有很多缺点
4.2) 单例法的优缺点(官方推荐)
  • 优点:1) 简单易行 改动方便
    多个网络请求复用一个AFURLSessionManager,连续发两个网络请求,用Wireshark抓包可以看到,第二次网络请求复用了第一次的TCP连接,没有做三次握手。

  • 缺点 : 在某些情况下 一个manager 由于线程的原因 导致这个manager 出问题, 对象逻辑出问题, 所有后续的网络都没法 复现 , app出现过少量ios12的用户网络失败之后 ,再也无法联网, 通过判断多次失败的方式, 重新构建一个manager , AFN的源码 例子 也是以单例的方式, app出现的问题 估计还是其他问题引起

内存泄漏的危害

下面的classA , 60个类对象未释放就会导致1.67M 内存的增加

#import <Foundation/Foundation.h>
#import "ClassB.h"
@class ClassB;
@interface ClassA : NSObject
@property(nonatomic,strong) ClassB  *classb;
@end

#import "ClassA.h"

@implementation ClassA

@end


image.png

6) demo 的链接

AFN内存泄漏demo

参考文献:
AFN为什么会内存泄漏

相关文章

网友评论

    本文标题:AFN内存泄漏的2种解决方法和对内存影响对比(附demo)

    本文链接:https://www.haomeiwen.com/subject/udhsvqtx.html