一,检测方法:
1.手动review代码,通过-(void)dealloc()检测。
review代码是最简单直接的方法。review的可能是自己的代码或他人写的代码。一般控制器在内存释放的时候,会通过调用dealloc方法来释放父类的对象。有一些需要手动释放的对象可以写在这里。如果有父类持有的对象无法释放,则不会调用dealloc方法。
2.通过xcode自带的instruments->leak工具检测。
Leaks instrument 记录你程序中所有发生分配内存的事件,而且周期性的搜索程 序可写内存,寄存器,和任何活跃内存块的栈引用。如果在这些地方找到一个没有对 于引用的内存块,它会告知缓冲区发生了一个泄露,并在详细面板里面显示相关的信息。
3.通过第三方工具检测。
项目可以通过集成Fabric,上传dSYM文件,就可以检测到一些奔溃信息,一般大多数都是内存泄露引起的。通过分析Fabric定位的崩溃日志,可以定位到代码模块进行内心泄露的修复和优化。
二,手动检测代码修复:
1.delegate强引用导致内存无法释放,需要用弱引用定义,否则会导致内存的循环引用;
@property (nonatomic,assign) id <ABCViewDelegate> delegate;
2.控制器vc传入自定义的vc或model时,用弱引用,因为控制器本身已经是强引用了。
@property (nonatomic,assign) xBaseVC *baseVC;
3.block里面有self调用的方法时,应该用__weak和__strong修饰一下,避免循环引用。
//定义宏,防止block泄露
#define VPWeakObj(o) autoreleasepool{} __weak typeof(o) o##Weak = o;
#define VPStrongObj(o) autoreleasepool{} __strong typeof(o) o = o##Weak;
//应用
@VPWeakObj(self);
[[AlipaySDK defaultService] payOrder:payInfo fromScheme:kAppSchema callback:^(NSDictionary *resultDic) {
@VPStrongObj(self);
[self doSomething];
}];
4.当用到通知时,需要在dealloc中释放一下。
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
5.定时器runloop引起的循环引用。可以通过GCD代替NSTimer避免定时器引起的循环引用问题,注意block的修饰.
__weak typeof(self) weakSelf = self;
[[JX_GCDTimerManager sharedInstance] scheduledDispatchTimerWithName:myTimer
timeInterval:5.0
queue:nil
repeats:YES
actionOption:AbandonPreviousAction
action:^{
[weakSelf doSomething];
}];
6,第三方库引起的内存泄露.
比如由于ASI无人维护,随着系统更新换代引起的内存泄露问题;还有类似访问相册,二维码生成的一些第三方库引起的内存泄露。解决办法是替换掉旧的第三方库,如果是单页面引用的,可以通过修改代码来修复内存泄露问题。
三,通过leak instruments工具检测。
运行代码到真机或模拟器上,点击product-profile打开instruments工具,点击leak工具,可以进行内存泄露的检测。红色x表示内存泄露,绿色√表示内存正常。
(1)打开profile
打开profile(2)选择leaks
选择leak
(3)运行进行检测
leak检测(4)分析结果,定位内存泄露的位置
定位内存泄漏文件 定位内存泄漏代码四,通过集成Fabric定位内存泄露, 是上传图片的地方发生了内存泄露。
1.通过cocoapod集成Fabric:https://fabric.io/
//注册fabric创建应用;2.脚本设置;3.plist配置;4.以下代码注册触发;
[Fabricwith:@[[Crashlyticsclass]]];
2.上传dSYM文件:打开ipa包的包内容,可以找到dSYM文件。上传到Fabric网页后台。
3.监测fabric的通知,进入后台查看崩溃日志。
fabric后台崩溃日志
扩展阅读:iOS 内存泄漏监测自动化
网友评论