UINavigationController hidesBarOnSwipe内存泄漏问题

pol*_*ech 5 memory-leaks objective-c uinavigationbar uinavigationcontroller ios

我的hidesBarOnSwipe财产有问题UINavigationController.

概述:

链接到项目文件

我有一个名为FirstViewController的控制器,它是根视图UINavigationController.一切都在Main.storyboard.FirstViewController包含UIButton操作.在该操作中,我实例化一个SecondViewController并将其推送到导航堆栈.

- (IBAction)button:(id)sender {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

    [self.navigationController pushViewController:vc animated:YES];
}
Run Code Online (Sandbox Code Playgroud)

在SecondViewController中,只有一个hidesBarsOnSwipe属性设置为YESon viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.hidesBarsOnSwipe = YES;
}
Run Code Online (Sandbox Code Playgroud)

和dealloc得到NSLogged:

- (void)dealloc {
    NSLog(@"Dealloc");
}
Run Code Online (Sandbox Code Playgroud)

问题:

当我们向上滑动以隐藏navigationBar时,dealloc永远不会被调用.Instruments在这里显示SecondViewController内存泄漏.

当我们在SecondViewController上,我们只需按下后退按钮 - 一切都很好.Dealloc被召唤.

肯定有某种保留周期,但我不知道为什么以及如何避免这种情况.

pol*_*ech 2

一些更新和临时解决方案:

还有另一种方法可以执行navigationBar隐藏。对我有用的是使用:

[self.navigationController setNavigationBarHidden:hidden animated:YES];
Run Code Online (Sandbox Code Playgroud)

为了获得良好的结果,请在类中添加一个属性来跟踪 navigationBar 动画的状态:

@property (assign, nonatomic) BOOL statusBarAnimationInProgress;
Run Code Online (Sandbox Code Playgroud)

UIScrollViewDelegate像这样实现:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat yVelocity = [scrollView.panGestureRecognizer velocityInView:scrollView].y;
    if (yVelocity > 0 && !self.statusBarAnimationInProgress) {
        [self setNavigationBarHidden:NO];
    } else if (yVelocity < 0 && !self.statusBarAnimationInProgress) {
        [self setNavigationBarHidden:YES];
    }
}
Run Code Online (Sandbox Code Playgroud)

设置隐藏导航栏应如下所示:

- (void)setNavigationBarHidden:(BOOL)hidden {
    [CATransaction begin];
    self.statusBarAnimationInProgress = YES;
    [CATransaction setCompletionBlock:^{
        self.statusBarAnimationInProgress = NO;
    }];
    [self.navigationController setNavigationBarHidden:hidden animated:YES];
    [CATransaction commit];
}
Run Code Online (Sandbox Code Playgroud)

我使用 CATransaction 检查导航栏的动画是否完成。任何有效的方法。不是那么简单的解决方案,但至少没有泄漏:)