为啥我的视图在内存不足警告时消失了?
Posted
技术标签:
【中文标题】为啥我的视图在内存不足警告时消失了?【英文标题】:Why is my view disappearing on low memory warning?为什么我的视图在内存不足警告时消失了? 【发布时间】:2011-01-20 18:55:04 【问题描述】:我的应用有一个标签栏控制器,其中一个标签项是拆分视图控制器。它的主视图控制器(即在索引 0 处)是一个从 nib 加载的导航控制器,因为它是自定义导航栏。
如果这听起来有点晦涩难懂,那是因为 1) 无法将 SVC 添加到 IB 中的 TBC 和 2) ios 4.2 splitview-navbar-colorTint 错误。事实上,直到昨天实施解决方法后,我才遇到内存不足警告的问题。
在解决方法之前,我使用 2 个导航控制器启动 SVC,并将其添加到 TBC 中(由于 IB 对标签栏的限制)并且没有问题 - 好吧,除了那个苹果错误。
小workaround demo 也可以正常工作,即使在内存不足警告之后。但它不涉及标签栏的额外开销。
但在my adaption of the workaround demo 中,它开始变成梨形。在显示拆分视图时发送内存不足警告,整个左侧(主视图)消失。设备上的行为相同,事实上我是在那里第一次发现的。
我对发生了什么感到困惑。显示的视图(导航 cont 的根视图)由表视图子类控制。我已经覆盖了 didReceiveMemoryWarning 但这没有帮助。此外(相应地!),超级视图不是零。这是一个 UITableView。完全正确。
所以,我在想导航控制器正在被释放?但是哪里?为什么不在原始演示中?现在的不同是添加了我的标签栏控制器。这是我将其添加到标签栏的代码:
- (void) addTabItemSplitViewWithNavConRoot:(BOOL)hasRootNC
// init master/detail views
SV1RootViewController *rvc = [[SV1RootViewController alloc] initWithNibName:@"SVC1RootView" bundle:nil];
SV1DetailViewController *dvc = [[SV1DetailViewController alloc] initWithNibName:@"SVC1DetailView" bundle:nil];
rvc.detailViewController = dvc;
UINavigationController *nc = nil;
if (hasRootNC)
nc = [self.pSVC1.viewControllers objectAtIndex:0];
nc.viewControllers = [NSArray arrayWithObjects:rvc, nil];
nc.navigationBar.tintColor = [UIColor redColor];
else
nc = nil;
UIViewController *vc = (hasRootNC)? (UIViewController*)nc :rvc;
UISplitViewController *svc = [self newSplitViewControllerWithMasterVC:vc detailVC:dvc];
svc.delegate = dvc;
// init the tab bar item
svc.tabBarItem = [[UITabBarItem alloc] initWithTitle:(hasRootNC)? @"SplitView with Nav Root":@"Simple SplitView"
image:nil
tag:0];
// int the split view
NSMutableArray *controllersArray = [NSMutableArray arrayWithArray:self.pTabBarController.viewControllers];
[controllersArray addObject:svc];
[self.pTabBarController setViewControllers:controllersArray];
// cleanup
[nc release];
[rvc release];
[dvc release];
[svc release];
- (UISplitViewController*) newSplitViewControllerWithMasterVC:(UIViewController*)masterView
detailVC:(UIViewController*)detailView
UISplitViewController *svc = [[UISplitViewController alloc] init];
NSMutableArray *controllersArray = [NSMutableArray arrayWithObjects:masterView, detailView, nil];
[svc setViewControllers:controllersArray];
return svc;
请问有人对我有什么想法吗? :)
快把我逼疯了!!!
【问题讨论】:
请尝试重新格式化您的代码。 【参考方案1】:解决了。与以编程方式初始化拆分视图控制器的奇怪组合有关,但将其注入从主窗口 xib 读取的导航控制器(所有这些都是因为 Apple 错误所需的自定义工具栏)。但我的猜测是来自 xib 的导航控制器正在卸载它的视图。
所以现在我只是从 nib 中取出整个 SVC,而不是手动构建它。实际上要简洁得多。
哦,伙计。我被an answer to this question(“指定”答案!)误导了。我现在刚刚注意到,这个更简单的方法也作为答案给出,实际上是最受欢迎的。完全忽略了它! ^^
【讨论】:
谢谢!我因完全相同的问题而发疯。一旦我用 IB 组织了一些事情,事情就开始按他们应该的方式工作了。【参考方案2】:没有看到所有代码,我猜在内存警告期间非活动视图被破坏了。 (上面写着'didReceiveMemoryWarning'的代码,你可能有[super didReceiveMemoryWarning])
您需要确保在您的 loadView 方法中,任何需要添加的子视图都重新添加到视图中,并相应地进行布局。希望对您有所帮助。
或者,如果您匆忙或懒惰,请阻止所有常见的事情发生。这可能很糟糕,可能会导致崩溃,但如果您不耐烦,这是另一种方法。
- (void)didReceiveMemoryWarning
//do nothing
//[super didReceiveMemoryWarning];
【讨论】:
正如我写的“我已经覆盖了 didReceiveMemoryWarning 但这没有帮助。此外(相应地!),超级视图不是零。它是一个 UITableView。正确如此。”我没有明确说,但是是的,我确实将 msg 删除为 super。 loadView 是什么样的?您可以尝试从数据源/委托那里重新加载 UITableView 吗?类似 [self.tableView reloadData] 的东西? Hm.. 视图是从属于 (SV1RootViewController*)rvc 的 nib SVC1RootView 加载的。依次将rvc写入(UINavigationController*)nc.viewControllers,用于初始化拆分视图控制器,分配给一个tabBarItem,添加到MainWindow.xib的标签栏控制器,调用后立即将其视图添加到窗口中上述方法。所以我没有直接连接到 loadView 。还是我?!? 我的模糊想法是导航控制器,源自 MainWindow.xib 正在发布? UITableView 是它自己的数据源/委托,所以我会在哪里调用 reloadData?来自 didReceiveMemoryWarning?以上是关于为啥我的视图在内存不足警告时消失了?的主要内容,如果未能解决你的问题,请参考以下文章
Instruments 指出内存不足警告,但内存使用率非常低