美文网首页iOS经验总结
iOS快速有效的解决内存泄露

iOS快速有效的解决内存泄露

作者: 正义从不缺席 | 来源:发表于2019-02-01 15:48 被阅读0次

1.使用xcode的Debug Memory Graph来查看内存引用关系

以下代码,很明显的循环引用:viewController引用object, object通过delegate引用viewController

@interface MyObject : NSObject
@property (nonatomic, strong) id delegate;
@end

@implementation MyObject

@end

@interface ViewController ()
@property (nonatomic, strong) MyObject *object;
@end

@implementation ViewController

- (void)dealloc {
    NSLog(@"%s", __func__);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    _object = [MyObject new];
    _object.delegate = self;
}

@end

我们打开Debug Memory Graph来看一下:

09C6697F-D88B-454D-8B13-9367A54935AF.png 屏幕快照 2019-02-01 15.09.56.png

可以很明显看到对象的引用关系,从而解决内存泄露,如果viewController被一个block强引用住,看看结果是怎样:

- (void)viewDidLoad {
    [super viewDidLoad];
    // 理论上10000000s后 viewController才会被释放
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10000000 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.view.backgroundColor = UIColor.redColor;
    });
}

Debug Memory Graph结果:

AFCE4C42-8771-47B5-A473-4D0D166CC4BC.png

⤴️⤴️⤴️⤴️⤴️只知道被一个block引用住了,但具体是哪个block,代码在哪里?无法查找。对于这种问题我们可以尝试使用Instruments

2.使用Instruments来查找内存泄露

接着上面的问题
1.将Build Setting->Debug Information Format->Debug设置为DWARF with sSYM File,重新run app
2.打开Xcode->Open Developer Tool-> Instruments选择Leaks

选择需要调试的app,点击小红点,开始记录

265D7414-6A64-410D-B1E5-458E55035E79.png

复现刚刚的内存泄露,搜索泄露的类

E421A319-4124-48E5-9554-9C96CE6A8C10.png

点击箭头

94C0F26A-B2F9-4849-82F0-4983BDFB4EF7.png

继续

CE44A5E1-E757-4A9C-B583-97871A067D25.png

ok,到了最后一步, 这里就是这个对象的内存引用历史记录了

2BA7C09F-ECCF-4D63-BD87-5EE219EFB14E.png

通过观察,我们不难发现上面的retain和release都是成对出现的,最后一步只有retain没有release操作,这一就是导致未释放的原因,可以看到是viewDidLoad方法触发的,刚好与我们的垃圾代码相吻合😂

总结:Debug Memory Graph 和 Instruments配合使用,基本上所有的内存泄露都能快速方便的查找出来

相关文章

网友评论

    本文标题:iOS快速有效的解决内存泄露

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