美文网首页
iOS 自定义一个简易内存检测工具

iOS 自定义一个简易内存检测工具

作者: wp_Demo | 来源:发表于2019-01-02 18:31 被阅读0次

    也是在看过开源代码MLeaksFinder受到的启发,写一个很简单的检测内存泄露的工具,我们知道向一个已经被销毁的对象发送消息是不会崩溃的,假如一个VC存在内存泄露,那么它就不会被释放掉,我们可以想向它发送消息,如果它收到了消息,那么这个VC的代码就一定存在问题.

    代码实现思路:可以在VC中设置一个属性,viewWillAppear的时候设置为NO,pop返回出栈的时候(暂时只考虑pop情况)设置为YES,我们在viewDidDisappear中,延迟访问这个这个属性,如果他为YES,那么就代表存在内存问题.

    新建一个VC的Category:UIViewController+LeaksTest

    hook:viewWillAppear,设置自定义属性的值为NO;viewDidDisappear中延迟访问属性

    const char * WPVCPOPFLAG;
    
    @implementation UIViewController (LeaksTest)
    + (void)load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self wp_swizzleOriginSEL:@selector(viewWillAppear:) currentSEL:@selector(wp_viewWillAppear:)];
            [self wp_swizzleOriginSEL:@selector(viewDidDisappear:) currentSEL:@selector(wp_viewDidDisappear:)];
        });
    }
    
    + (void)wp_swizzleOriginSEL:(SEL)originSEL currentSEL:(SEL)currentSEL{
        Method originMethod  = class_getInstanceMethod([self class], originSEL);
        Method currentMethod  = class_getInstanceMethod([self class], currentSEL);
        method_exchangeImplementations(originMethod, currentMethod);
    }
    
    -(void)wp_viewWillAppear:(BOOL)animated
    {
        [self wp_viewWillAppear:animated];
        objc_setAssociatedObject(self, WPVCPOPFLAG, @(NO), OBJC_ASSOCIATION_RETAIN);
    }
    
    -(void)wp_viewDidDisappear:(BOOL)animated
    {
        [self wp_viewWillAppear:animated];
        
        if ([objc_getAssociatedObject(self, WPVCPOPFLAG) boolValue]) {
            //发送消息
            [self willDelloc];
        }
    }
    
    - (void)willDelloc{
        __weak typeof(self) weakSelf = self;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf isNotDelloc];
        });
    }
    
    - (void)isNotDelloc{
        NSLog(@"%@ IS NOT DELLOC",NSStringFromClass([self class]));
    }
    

    在这个VC出栈的时候,设置自定义属性的值,创建UINavigationController+LeakTest

    @implementation UINavigationController (LeakTest)
    + (void)load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            [self wp_swizzleOriginSEL:@selector(popViewControllerAnimated:) currentSEL:@selector(wp_popViewControllerAnimated:)];
        });
    }
    
    + (void)wp_swizzleOriginSEL:(SEL)originSEL currentSEL:(SEL)currentSEL{
        Method originMethod  = class_getInstanceMethod([self class], originSEL);
        Method currentMethod  = class_getInstanceMethod([self class], currentSEL);
        method_exchangeImplementations(originMethod, currentMethod);
    }
    
    - (UIViewController *)wp_popViewControllerAnimated:(BOOL)animated{
        extern const char *WPVCPOPFLAG;
        UIViewController *popViewController = [self wp_popViewControllerAnimated:animated];
        objc_setAssociatedObject(popViewController, WPVCPOPFLAG, @(YES), OBJC_ASSOCIATION_ASSIGN);
        return popViewController;
    }
    @end
    

    我们存在循环引用的代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        self.str = @"123";
        self.block = ^{
            NSLog(@"%@",self.str);
        };
        // Do any additional setup after loading the view.
    }
    

    2019-01-02 18:12:47.991684+0800 CustomLeakTest[42603:920435] TestViewController IS NOT DELLOC
    最后附上demo地址:https://github.com/gnaw9258wp/CustomLeak.git

    相关文章

      网友评论

          本文标题:iOS 自定义一个简易内存检测工具

          本文链接:https://www.haomeiwen.com/subject/szxtrqtx.html