内存警告会破坏呈现视图控制器吗?

时间:2012-01-27 13:27:53

标签: objective-c ios ipad memory-management presentmodalviewcontroller

我有一个iPad应用程序,它有一个主视图控制器,然后是一个设置视图控制器。当我的主视图显示设置视图时,我以全屏显示设置视图。设置视图中有一个关闭按钮,它可以工作 - 直到发生内存警告。如果在屏幕上显示设置按钮时发生内存警告,则会拒绝解除。

换句话说,这有效:

  • App Launch - >显示主视图 - >显示设置视图 - >关闭设置视图

这不是:

  • App Launch - >显示主视图 - >显示设置视图 - >内存警告 - >关闭设置视图

设置视图将保留在那里。

我在第一代iPad上运行iOS 5上的应用程序。 (我不支持iOS 4。)

我该如何解决这个问题?

修改

以下是我显示设置视图的代码:

- (void) showSettings{

    if (!self.settingsViewController) {

    //Create the navigation controller and the root view for the settings panel
    SettingsViewController *settingsRootView = [[SettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
    UINavigationController *settingsView = [[UINavigationController alloc] initWithRootViewController:settingsRootView];
    [settingsRootView release];

    //Configure the animation and modal style, and the navigation bar's color

    [settingsView.navigationBar setTintColor:kDarkGrayColor];

    //Enable the settings flag
    [self setSettingsIsActive:YES]; 

    //Configure the presentation
    [settingsView setModalPresentationStyle:UIModalPresentationFullScreen];
    [settingsView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];

    self.settingsViewController = settingsView;

    [settingsView release];
    }

    //present and release the settings panel
    [self presentViewController:self.settingsViewController animated:YES completion:^{

    }];

}

这就是我隐藏的方式:

//This method reloads some stuff and 
- (void) dismissSettings{

    //
    //  ... Reload some other stuff...
    //

    //Dismiss the settings panel
    [self dismissViewControllerAnimated:YES completion:^{

    //
    //  ... Reload some other stuff...
    //

    }]; 
}

2 个答案:

答案 0 :(得分:4)

原则上,内存警告不会对视图控制器执行任何操作,但会卸载当前未在屏幕上显示的视图控制器的视图。

在您的特定情况下,我会在您的设置视图控制器中查找可能在主视图控制器视图中引用某些内容的代码。如果是这种情况,可能在内存警告发生后,引用将为零。

此外,您应该验证didReceiveMemoryWarning方法的实现,看看您是否正在处理可能需要的东西来解雇该设置视图。

在内存不足的情况下,将卸载那些“非活动”视图控制器中的所有视图。当您在主控制器上声明dismissSettings方法时,在调用它时,主视图中的所有元素很可能都是零。我不知道“重新加载其他东西”代码中包含哪些操作,但我想与视图相关的一些操作会使方法失败。

我建议将与视图相关的所有重新加载代码移动到viewDidAppear方法,因为它将保证加载视图。

另一方面,我建议你在实际设置视图控制器上移动实现dismiss方法(记住它应该像[ self.navigationController dismissModalViewControllerAnimated:YES];那样你需要关闭导航控制器)。至少,这是我一直这样做的方式,从来没有让我失望。逻辑是我不希望非活动视图控制器运行任何逻辑。

最后,当您提到您的目标是iOS 5及更高版本时,我强烈建议您将项目移至ARC。它比看起来更容易,而且一旦你移动了,它就真的很棒。

您遇到问题的另一个可能原因是您使用通知调用了您的dismiss方法,并且您的主控制器正在取消订阅viewDidUnload方法上的通知。请记住,当低内存条件触发时,将调用viewDidUnload方法!

答案 1 :(得分:0)

首先要找出导致内存警告的原因。使用仪器并检查是否有泄漏。如果您使用ARC,这应该是一个问题 - 但显然发生内存警告是严重错误的。解决这个问题,你已经解决了问题。

也就是说,当内存开始变短时,操作系统将关闭应用程序。后台应用程序通常是第一个应用程序,但很多时候如果泄漏程度足够严重,那么后台应用程序终止之间的时间段和正在运行的应用程序也被终止的时间可能很短。