内存泄漏的常见情况
1、对象之间的循环引用,循环引用的实质是:多个对象之间相互有强引用,不能释放让系统回收,解决办法:使用weak
打破对象的相互应用。
2、Block
的循环引用,block
在copy
的时候都会对block内部的对象进行强引用,解决办法:使用_weak
打破循环,此方法只能在ARC有效;在MRC下应该使用一下
_blcok _weak typeof(self) weakSelf = self;self.myBlock = ^(){}
3、delegate
的循环引用,delegate
是委托模式(将一件属于委托者的事情,交给另外一个被委托者来处理),这里可能会出现委托者和被委托者之间的相互强引用;解决办法:在声明delegate
属性的时候用weak进行弱引用或者通过中间对象(代理对象)的方式来解决。(效率更高的中间对象NSProxy
,不需要进行发送消息和再动态解析,直接进行消息转发)
4、CADisplayLink
、NSTimer
会对target
产生强引用,如果target
又对他们产生强引用,那么就会产生循环引用;解决办法:NSTimer
有一个block
的方法,我们可以利用block
的弱指针来解决
_weak typeof(self) weafSelf = self;传weakSelf进去。
5、通知的循环引用,iOS9以后一般的通知都不需要手动进行移除观察者,系统会自动在dealloc
的时候调用[[NSNotificationCenter defaultCenter] removeObserver: self]
。iOS9以前的需要手动的进行移除。原因:iOS9以前的观察者注册时,通知中心并不会对观察者对象做retain
操作,而是进行了unsafe_unretained
引用,所以在观察者被回收的时候,如果不对通知进行手动移除,那么指针指向被回收的内存区域就会成为野指针,这时再发送通知,便会造成程序崩溃。从iOS9开始通知中心会对观察者进行weak弱引用,这时即使不对通知进行手动移除,指针也会在观察者被回收的时候自动置空,这时再发送通知,向空指针发送消息是不会有问题的。但是建议最好还是加上移除通知的操作
(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self.observer name:@"name" object:nil]; }
6、WKWebView造成的内存泄漏;总的来说WKWebView不管是性能还是功能,都要比UIWebView强大的很多,本身也不存在什么内存泄漏的问题,但是如果开发者使用不当的话还是会造成内存泄漏的,addScriptMessageHandler
这个操作导致了WKWebView对self进行了强引用,然后addSubview
这个操作,也让self对WKWebView进行了强引用,这就造成了循环引用;解决方法就是在合适的机会里对MessageHandler
进行移除操作
(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [_wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"WKWebViewHandler"];
内存泄漏的查询
1、Analyze静态分析(command + shift + b)也就是编译,主要分析以下四种问题:
①、逻辑错误:访问空指针或未初始化的变量等;
②、内存管理错误:如内存泄漏等;
③、声明错误:从未使用过的变量;
④、Api调用错误:未包含使用的库和框架;
2、
Instruments
中的Leak
动态分析内存泄漏,product->profile ->leaks 打开工具主窗口
3、Facebook早已开源了一款检测内存问题的三方库FBRetainCycleDetector
网友评论