美文网首页
MLeaksFinder 分析2:基本流程

MLeaksFinder 分析2:基本流程

作者: dc630f46ee2d | 来源:发表于2017-10-18 16:28 被阅读0次

这一次,我们创建一个最简单的视图控制器不被释放的场景,通过断点调试的方法,来简单梳理一下。

准备

新建一个视图控制器AAViewController添加block.不使用__weak引用,这样就会构造循环引用的最基本的场景。

@interface AAViewController ()
@property (nonatomic, copy) dispatch_block_t block;
@end

@implementation AAViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.block = ^(){
        NSLog(@"%@", self);
    };
}
@end

将它入导航控制器的栈。然后点击返回按钮,退出该视图控制器,会发现出现一个提示循环引用的弹框。

屏幕快照 2017-10-17 下午4.08.26.png

调试

全局搜索UIAlertView,找到该库中只有一个地方调用了UIAlertView.是在MLeaksMessenger的一个类方法

+ (void)alertWithTitle:(NSString *)title
               message:(NSString *)message
              delegate:(id<UIAlertViewDelegate>)delegate
 additionalButtonTitle:(NSString *)additionalButtonTitle {
    [alertView dismissWithClickedButtonIndex:0 animated:NO];
    UIAlertView *alertViewTemp = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:delegate
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:additionalButtonTitle, nil];
    [alertViewTemp show];
    alertView = alertViewTemp;
    
    NSLog(@"%@: %@", title, message);
}

在这里打一个断点。可以看到整个调用栈。

屏幕快照 2017-10-18 下午3.10.50.png

定位到了调用方法的源头是 willDealloc。搜索看到UIViewControllercategory中有该方法。显然它这就是未被释放控制器AAViewController调用的方法。

- (void)swizzled_viewDidDisappear:(BOOL)animated {
    [self swizzled_viewDidDisappear:animated];
    
    if ([objc_getAssociatedObject(self, kHasBeenPoppedKey) boolValue]) {
        [self willDealloc];
    }
}

其中swizzled_viewDidDisappear 是和viewDidDisappear交换的方法。那么说明这个方法即是视图控制器调用viewDidDisappear的时机执行。调用要满足[objc_getAssociatedObject(self, kHasBeenPoppedKey) boolValue] 为true.全局搜索kHasBeenPoppedKey ,发现是在UINavigationController+MemoryLeak- (UIViewController *)swizzled_popViewControllerAnimated:(BOOL)animated中设置为@(YES).它也是导航控制器popViewControllerAnimated:的交换方法,也就是说每次导航控制器pop AAViewController的时候,就将kHasBeenPoppedKey设置为YES。因为AAViewController从导航控制器Pop后,认为视图控制器应该被释放。

相关文章

网友评论

      本文标题:MLeaksFinder 分析2:基本流程

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