更改rootviewcontroller导致内存泄漏

MNI*_*RAM 7 memory-leaks ios automatic-ref-counting

在询问我自己的问题之前,我检查了所有的问题,但它们都不适合我.

当我在第一次运行时打开我的应用程序时,我调用了FirstViewController(它包含两个按钮:注册或登录).如果用户选择注册,我会带上RegisterViewController(它包含一个按钮,让用户登录以防他改变主意).最后一个LoginViewController(还包含一个打开注册屏幕的按钮)

FirstViewController中两个按钮的代码

- (IBAction)signupPressed:(id)sender {
    AppDelegate *app = (AppDelegate*) [UIApplication sharedApplication].delegate;
    app.window.rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"RegisterViewController"];
}

- (IBAction)loginPressed:(id)sender {
    AppDelegate *app = (AppDelegate*) [UIApplication sharedApplication].delegate;
    app.window.rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
}
Run Code Online (Sandbox Code Playgroud)

RegisterViewController按钮的代码,通向LoginViewController(我尝试过其中一个解决方案,但失败了)

- (IBAction)loginPressed:(id)sender {
    AppDelegate *app = (AppDelegate*) [UIApplication sharedApplication].delegate;


    UIViewController *previousRootViewController = app.window.rootViewController;

    app.window.rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];

    // Nasty hack to fix http://stackoverflow.com/questions/26763020/leaking-views-when-changing-rootviewcontroller-inside-transitionwithview
    // The presenting view controllers view doesn't get removed from the window as its currently transistioning and presenting a view controller
    for (UIView *subview in app.window.subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UITransitionView")]) {
            [subview removeFromSuperview];
        }
    }
    // Allow the view controller to be deallocated
    [previousRootViewController dismissViewControllerAnimated:NO completion:^{
        // Remove the root view in case its still showing
        [previousRootViewController.view removeFromSuperview];
    }];
}
Run Code Online (Sandbox Code Playgroud)

LoginViewController:指向RegisterViewController的代码.

- (IBAction)signupPressed:(id)sender {
    AppDelegate *app = (AppDelegate*) [UIApplication sharedApplication].delegate;
    app.window.rootViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"RegisterViewController"];
}
Run Code Online (Sandbox Code Playgroud)

上面提到的代码总是创建一个新实例,我使用Instruments跟踪了应用程序.

单击FirstViewController上的注册创建RegisterViewController的第一个实例

当点击第一个屏幕上的注册按钮时

单击登录按钮(RegisterViewController),然后单击注册按钮(LoginViewController) 点击登录屏幕上的注册按钮

这两个实例都是由UIKit发布的

仪器中的细节

有没有机会管理这些泄漏?