OC UIWindow setRootViewController切换界面引发的内存问题
2018年12月5日iOS Standard
[转载请注明出处]
相信很多人都有这样的需求,直接从UIWindow层面切换主界面,如引导界面 -> 登录界面, 登录界面 -> Home,
以引导->登录 为例,一般人都会查到两种方案:
1、KeyWindow在下层,引导页新建Window,覆盖在KeyWindow之上;
2、KeyWindow直接做引导,引导完成后通过setRootViewController更换为登录界面。
第一种方案是比较理想的,但也不是没有坑,不够熟悉的话也可能释放不掉,而且需要上下两个window同时加载。此方案暂不在本文讨论之列。
第二种容易出现内存问题,主要原因大部分是因为在rootViewController上进行了presentViewController。
直接先上解决方案:
UIViewController *rootVc = [UIApplication sharedApplication].delegate.window.rootViewController; [[UIApplication sharedApplication].delegate.window setRootViewController:newRootVc]; for (UIView *subView in rootVc.view.subviews) [subView removeFromSuperview]; [rootVc dismissViewControllerAnimated:NO completion:nil];
解析:
下列语句可保证present的ViewController被释放:
[rootVc dismissViewControllerAnimated:NO completion:nil];
下列语句保证rootVc资源释放:
for (UIView *subView in rootVc.view.subviews) [subView removeFromSuperview];
最后附上带动画切换的完整方案:
__weak UIViewController *weakRoot = [UIApplication sharedApplication].delegate.window.rootViewController; Animation animation = ^{ BOOL oldState = [UIView areAnimationsEnabled]; [UIView setAnimationsEnabled:NO]; [[UIApplication sharedApplication].delegate.window setRootViewController:newRootVc]; [UIView setAnimationsEnabled:oldState]; }; [UIView transitionWithView:[UIApplication sharedApplication].delegate.window duration:0.5f options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionPreferredFramesPerSecond60 animations:animation completion:nil]; //释放rootVc中的资源,否则可能出现内存泄露 for (UIView *subView in weakRoot.view.subviews) [subView removeFromSuperview]; [weakRoot dismissViewControllerAnimated:NO completion:nil];
发表评论或回复