检测循环引用方法
- 引入开源库MLeaksFinder
- 在Dealloc中打log,判断是否销毁
- Instruments中Leaks查看内存泄漏
循环引用
1.WKWebview 中JS和OC交互,引起循环引用
[self.wkWebview.configuration.userContentController addScriptMessageHandler:self name:@"wkWebview"];
这个代码中。
self->wkWebview->configuration->userContentController->self
造成循环引用
需要在viewWillDisapper:中移除scriptMessage。
[self.wkWebview.configuration.userContentController removeScriptMessageHandlerForName:@"wkWebview"];
2.Cell中包含按钮等点击事件,用Block来实现这个回调
image
cell是UITableView的子视图,每个子视图都是被其父试图的subviews(NSArray*)属性所强引用,即:self->tableView->subviews->cell。而cell因为回调强引用了Block内部的对象,形成了循环引用链条。cell->Block->self。解决的方式是使用弱引用来传入Block。
在Cell的Block中不要用方法上的tableView。这样还是会造成循环引用,应该使用self.tableView来实现。
3.在单例中不要传入View,被强引用,不能释放,造成内存泄露
4.MLeaksFinderBug,系统控件内存泄漏:UIImagePickerController、UIAlertController
NSObject+MemoryLeak类别,
方法+ (NSMutableSet *)classNamesWhitelist中添加白名单。
+ (NSMutableSet *)classNamesWhitelist {
static NSMutableSet *whitelist = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
whitelist = [NSMutableSet setWithObjects:
@"UIFieldEditor", // UIAlertControllerTextField
@"UINavigationBar",
@"_UIAlertControllerActionView",
@"_UIVisualEffectBackdropView",
nil];
// System's bug since iOS 10 and not fixed yet up to this ci.
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
if ([systemVersion compare:@"10.0" options:NSNumericSearch] != NSOrderedAscending) {
[whitelist addObject:@"UISwitch"];
}
//UIImagePickerController加入白名单,不报内存泄漏
if ([systemVersion compare:@"10.0" options:NSNumericSearch] != NSOrderedAscending) {
[whitelist addObject:@"UIImagePickerController"];
}
});
return whitelist;
}
可以添加相应类的类别,添加白名单来忽略提示框
------------.h------------
#import <UIKit/UIKit.h>
@interface UIImagePickerController (MemoryLeak)
@end
------------.m------------
#import "UIImagePickerController+MemoryLeak.h"
#import "NSObject+MemoryLeak.h"
@implementation UIImagePickerController (MemoryLeak)
- (BOOL)willDealloc {
return NO;
}
@end
网友评论