ARC下可能的内存泄露

习惯csdn打草稿了……http://blog.csdn.net/zhuchuanwu2013/article/details/51284733

已习惯于arc帮我们管理内存的我们,写起代码来,比MRC似乎肆意妄为了许多,总有些有恃无恐的赶脚,其实arc下面还是很容易引起内存溢出的。 
这里写图片描述 
如何找出这些问题呢?

关于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(垃圾回收)。

也就是说只要我们稍不注意,隐式的持有或复制对象就会造成内存泄露,上图中的溢出都是我们项目中的,找了一下午原因,总算黄天不负有心人。

Block中变量的使用

image 
上面图片中就是一典型案例,红色部分就是修改之前导致内存溢出的代码,我们来分析一下: 
上面的success block应该是self持有,而在success中有持有了self,导致self和 block 的循环引用,造成内存泄露! 
说到底还是造成了循环引用导致了内存泄漏,所以我们要打破循环,释放对象,这里我们把self变成了弱引用,打破循环引用。关于block的变量引用 
link

NSNotificationcenter 需要 removeObserver

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

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

NSTimer

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

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

delegate属性的强引用

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

@interface SampleViewController

@property (nonatomic, strong) SampleClass *sampleClass;

@end

@interface SampleClass

@property (nonatomic, strong) SampleViewController *delegate;

@end

上例中,解决办法是把SampleClass 的delegate属性的strong改为assign即可。

其他

今天发现在使用WKWebView的时候,也特别容易出现内存泄露, 
[_webView.configuration.userContentController addScriptMessageHandler:self name:clickName];

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

[_webView.configuration.userContentController removeScriptMessageHandlerForName:clickName]; 
有点类似NSNotification的赶脚。

小技巧

以上几种情况可能通过instrument 是查看不出来的,至少是没有小红叉的。我们通过instruments查看所有VC的引用计数才找到那些VC是发生了内存泄露。 
写的不对的地方请大家指正。qq:1317272927 交流群:317120818 
欢迎骚扰!! 
青岛市崂山区松岭路青岛国际创新园 b-12 青岛酷特智能股份有限公司

发表评论

电子邮件地址不会被公开。 必填项已用*标注