ARC下的内存泄漏

已习惯于arc帮我们管理内存的我们,写起代码来,比MRC似乎肆意妄为了许多,总有些有恃无恐的感觉,其实arc下面还是很容易引起内存溢出的。

ARC 是帮助我们做对象内存管理的一套机制,使得我们以前在 MRC 模式下管理内存工作量能在 ARC 模式下得到缓解。正如苹果官方文档上所描述的:
Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory management of Objective-C objects.
可见 ARC 是编译时特性,它没有改变 Objective-C 引用计数式内存管理的本质,更不是 GC(垃圾回收)。
也就是说只要我们稍不注意,隐式的持有或复制对象就会造成内存泄露。

NSNotificationcenter

1
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(method:) name:@"notiName" object:nil];

这里添加观察者其实是不会造成内存泄漏的,但是,但是,但是……如果self被销毁,当在调用post消息的时候,就会报对象被释放的错误,导致闪退,所以在添加观察者的对象,一定要在它被销毁的时候从消息中心删除!

就是在注册通知的地方加上这个:

1
2
3
4
- (void)dealloc {

[[NSNotificationCenter defaultCenter]removeObserver:self];
}

NSTimer

1
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(method:) userInfo:nil repeats:YES];

上面的timer为了防止 target 被释放而导致的程序异常,timer 会持有 target, self 持有 timer,timer 在初始化时持有 self,造成循环引用。解决的方法就是使用 invalidate 方法销掉 timer。

delegate属性的强引用

delegate声明为strong属性容易导致内存溢出 。

解决办法是把delegate属性的strong改为assign或者weak即可。

  • 当用weakassign修饰的时候,指明该对象并不负责保持delegate这个对象,delegate这个对象的销毁由外部控制。
  • 当用strong修饰的时候,该对象强引用delegate,外界不能销毁delegate对象,会导致循环引用(Retain Cycles)。

WKWebView

1
[_webView.configuration.userContentController addScriptMessageHandler:self name:clickName];

添加addScriptMessageHandler之后,必须在vc销毁前把它移除。

1
[_webView.configuration.userContentController removeScriptMessageHandlerForName:clickName];

NSNotification 很类似。

Block

这里写图片描述

上面图片中就是一典型案例,红色部分就是修改之前导致内存溢出的代码,我们来分析一下:

上面的success block应该是self持有,而在success中有持有了self,导致self和 block 的循环引用,造成内存泄露!

说到底还是造成了循环引用导致了内存泄漏,所以我们要打破循环,释放对象,这里我们把self变成了弱引用,打破循环引用。

以上几种情况可能通过instrument 是查看不出来的,至少是没有小红叉的。我们通过instruments查看所有VC的引用计数才找到那些VC是发生了内存泄露。

参考他的

-------------本文结束感谢您的阅读-------------
分享使我快乐!