为啥我的视图在内存不足警告时消失了?

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 指出内存不足警告,但内存使用率非常低

应用程序收到内存不足警告但只有 5.7MB 的活动字节

UIImageView 不释放内存(根据 VM Tracker) - 内存不足警告和终止

新 iPad:内存不足警告未出现?

为啥我的 C# 应用程序中出现内存不足异常?

为啥使用JAVA的时候老显示内存不足?