美文网首页
OC中内存泄漏

OC中内存泄漏

作者: 苍眸之宝宝 | 来源:发表于2021-03-13 11:19 被阅读0次

1.简介

  何为内存泄漏?

内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

  在OC中的ARC环境下,两个或多个对象相互强引用造成引用环,内存不能释放,导致内存泄漏。

2.OC中内存泄漏的几种情况和解决办法

2.1对象间的循环引用

2.1.1普通对象的循环引用

  解决方法是将对象之间引用环的某一强引用(strong)改为弱引用(weak)。

// ClassA
@property (nonatomic, weak) ClassA * a;

// ClassB
@property (nonatomic, strong) ClassB * b;

2.1.2block循环引用

  对象持有block,而block中有直接或简介的访问了该对象,造成循环引用;解决方法在block内,用该对象的弱引用。

typedef int (^MySomeBlock) (int);
__weak typeof(self) weakself = self;
self.block = ^int(NSInteger i) {
  weakself.window;
  return i;
};

2.1.3delegate循环引用问题

  该情况在OC中广泛存在,是2.1.1的一种情况。

@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;

2.2NSNotification的观察者忘记移除

  在合适的时机将观察者进行移除,比如在viewWillDisappear或者dealloc中。观察者一种是不带block的,这类观察者iOS9.0后无需手动移除。另一种是block块的观察者,需要移除;如果不移除,由于观察者强持有block块,这样造成每个观察者都持有一个block。如果接收到通知,多个观察者都会调用该block,造成重复调用。所以,一定要合适的时机移除该类观察者。

[[NSNotificationCenter defaultCenter] removeObserver:self];

2.3NSTimer循环引用

  NSTimer强持有对象,对象强持有NSTimer时会造成循环引用;解决方法是在适当的时候调用NSTimer的invalidate方法;不要在强引用环中对象的dealloc中调用,否则不会打破引用环。

@interface NextViewController ()

@property (nonatomic, strong) NSTimer * timer;
@property (nonatomic, assign) NSInteger number;

@end

@implementation NextViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
//    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerEvent) userInfo:nil repeats:YES];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        self.number++;
        NSLog(@"%ld", (long)self.number);
    }];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self dismissViewControllerAnimated:YES completion:nil];
    [self.timer invalidate];
}

- (void)timerEvent {
    NSLog(@"NextViewController-timer");
}

- (void)dealloc
{
    NSLog(@"NextViewController-dealloc");
}

2.4非OC对象内存处理

  其它的对于CoreFoundation框架下的某些对象或变量需要手动释放(如CGContextRelease);C语言代码中的malloc等分配的内存,需要手动free释放内存。

+ (UIImage *)imageFromColor:(UIColor *)color size:(CGSize)size {
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGContextRelease(context);
    return img;
}

2.5大次数循环内存暴涨问题

  当循环次数较大,且循环体内局部变量占用内存较大时,会出现该问题;解决方法是将循环体代码放入缓存池中。

    NSMutableArray * imageList = [NSMutableArray new];
    for (NSInteger i = 0; i < 10000; i++) {
        @autoreleasepool {
            UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"image_%ld", i]];
            [imageList addObject:image];
            NSLog(image);
        }
    }

2.6加载大图片或者多个图片

  使用imageWithContentsOfFile替换imageNamed。

2.7 UIWebView

  在App中使用h5界面,使用WKWebView替换UIWebView;UIWebView在iOS12以后已经废弃,还是用WKWebView吧。

相关文章

  • OC中内存泄漏

    1.简介   何为内存泄漏? 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放...

  • iOS 内存泄漏之循环应用

    iOS中的内存泄漏可以分为两种: 被泄漏的内存已经没有对象对其持有,但是没有正常释放,主要是OC对象与C语言转换造...

  • Android 中常见的内存泄漏总结

    在 Android 开发中,稍有不慎就容易引起内存泄漏,我们经常听到内存泄漏,但是什么是内存泄漏呢? 内存泄漏:无...

  • A1_内存泄漏(循环引用)

    一、什么是内存泄漏,在 Obj-C 中如何检测内存泄漏? “内存泄漏(Memory Leak)是指程序中己动态分配...

  • iOS内存优化

    引起内存泄漏的原因 引起内存泄漏的原因主要有三类,如下 循环引用 强引用 非OC对象 1、循环引用。最简单的循环引...

  • 一些笔试题

    java内存相关 内存泄漏 在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并...

  • iOS内存泄漏的场景和检测

    内存泄漏的相关定义OC当中内存管理方式:ARC/MRCARC:自动引用计数(系统自动管理内存),由开发人员开辟内存...

  • Swift闭包循环引用

    无论OC中的Block还是Swift中的闭包Closure,经常因为使用不当从而造成循环引用从而导致内存泄漏,如何...

  • 安卓内存泄漏

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

  • Part1_Android内存泄漏总结

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...

网友评论

      本文标题:OC中内存泄漏

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