iOS 解决从不同界面跳转登录界面的视图释放问题

开发过程中,很多时候需要在特定的条件下跳转到登录界面重新登录。如果涉及的图层比较复杂,会导致视图不释放,占用内存。仔细分析下就很好解决。

1、判断出当前视图的层级,做视图释放处理。

- (UIViewController *)currentViewController {
    UIViewController * currVC = nil;
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    UIViewController * Rootvc = window.rootViewController ;
    do {
        if ([Rootvc isKindOfClass:[UINavigationController class]]) {
            UINavigationController * nav = (UINavigationController *)Rootvc;
            UIViewController * v = [nav.viewControllers lastObject];
            currVC = v;
            Rootvc = v.presentedViewController;
            continue;
        }else if([Rootvc isKindOfClass:[UITabBarController class]]){
            UITabBarController * tabVC = (UITabBarController *)Rootvc;
            currVC = tabVC;
            Rootvc = [tabVC.viewControllers objectAtIndex:tabVC.selectedIndex];
            continue;
        } else {
            currVC = Rootvc;
            Rootvc = nil;
        }
    } while (Rootvc!=nil);
    return currVC;
}

2、视图一般都是push和present混用。做视图释放

// 提示用户重新登录
UIViewController *currentVc = [self currentViewController];
// 1.判断当前是否在登录界面
if (![currentVc isKindOfClass:NSClassFromString(@"TTLoginController")]) {

    // 2.创建登录界面
    UIViewController *login = [UIViewController instantiateViewControllerWithIdentifier:@"TTLoginController"];
    // 通过KVC进行传值
    [login setValue:@(type) forKey:@"type"];

    UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    /* viewController.presentedViewController只有present才有值,push的时候为nil
     */

    // 代码块
    void(^block)(void) = ^(void) {
        [UIApplication sharedApplication].keyWindow.rootViewController = login;
        login.view.transform = CGAffineTransformMakeScale(0.2, 0.2);
        [UIView animateWithDuration:0.3 animations:^{
            login.view.transform = CGAffineTransformIdentity;
        }];
    };

    //防止重复弹
    if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController *navigation = (id)rootViewController.presentedViewController;
        if ([navigation.topViewController isKindOfClass:NSClassFromString(@"TTLoginController")]) {
            return; }
    }
    if (rootViewController.presentedViewController) {
        //要先dismiss结束后才能重新present否则会出现Warning: Attempt to present <UINavigationController: 0x7fdd22262800> on <UITabBarController: 0x7fdd21c33a60> whose view is not in the window hierarchy!就会present不出来登录页面
        [rootViewController.presentedViewController dismissViewControllerAnimated:false completion:block];
    }else { block(); }
}