Разрушает ли предупреждение памяти контроллер представления?
У меня есть приложение для iPad, которое имеет контроллер главного вида, а затем контроллер вида настроек. Когда мой основной вид представляет собой вид настроек, я представляю вид настроек в полноэкранном режиме. В представлении настроек есть кнопка "Закрыть", которая работает до тех пор, пока не появится предупреждение памяти. Если при нажатии кнопки настройки на экране появляется предупреждение памяти, оно не будет отключено.
Другими словами, это работает:- Запуск Приложения - > Показать Основной Вид -> Показать Вид Настроек - > Закрыть Просмотр Параметров
Это не так:
- Запуск Приложения - > Показать Основной Вид -> Показать Вид Настроек - > Предупреждение Памяти - > Закрыть Вид Настроек
Представление настроек просто останется там.
Я запускаю это приложение на iOS 5 на iPad первого поколения. (Я не поддерживаю 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 ответа:
В принципе, предупреждение памяти ничего не сделает с вашими контроллерами вида, но оно выгрузит представления тех контроллеров вида, которые в данный момент не отображаются на экране.
В вашем конкретном случае я бы искал что-нибудь в коде из вашего контроллера вида настроек, что могло бы ссылаться на что-то из представления главного контроллера вида. Если это так, то, вероятно, эта ссылка будет равна нулю после появления предупреждения памяти.
Кроме того, вы следует проверить вашу реализацию методов didReceiveMemoryWarning, чтобы увидеть, если вы избавляетесь от чего-то, что может потребоваться, чтобы отклонить это представление настроек.
При низком уровне памяти все представления из этих "неактивных" контроллеров будут выгружены. Поскольку ваш метод
dismissSettings
объявлен на главном контроллере, при его вызове очень возможно, что все элементы из вашего основного представления равны нулю. Я не знаю, какие операции содержатся в "перезагрузить некоторые другие stuff" код, но я предполагаю, что что-то связанное с представлением приводит к сбою метода.Я бы предложил переместить весь код перезагрузки, связанный с представлением, в метод
viewDidAppear
, поскольку он будет гарантированно иметь загруженный вид.С другой стороны, я бы рекомендовал вам переместить реализацию метода dismiss на фактический контроллер вида настройки (помните, что это должно быть что-то вроде
[ self.navigationController dismissModalViewControllerAnimated:YES];
, поскольку вам нужно отключить навигационный контроллер). По крайней мере, так я всегда поступал. это и никогда меня не подводило. Логика заключается в том, что я не хочу, чтобы неактивные контроллеры вида выполняли какую-либо логику.Наконец, поскольку вы упомянули, что ориентируетесь на iOS 5 и выше, я бы очень рекомендовал переместить ваш проект в ARC. Это легче сделать, чем кажется, и как только вы переехали, это действительно здорово.
Другая возможная причина вашей проблемы заключается в том, что вы вызываете свой метод увольнения с помощью уведомлений и что ваш главный контроллер отписывается от это уведомления о методе viewDidUnload. Имейте в виду, что метод viewDidUnload будет вызван при срабатывании условия нехватки памяти!
Первое, что нужно выяснить, что вызывает предупреждение памяти. Используйте инструменты и проверьте, нет ли утечек. Если вы используете ARC, это должно быть проблемой, но очевидно, что - то серьезно неправильно для предупреждения памяти. Исправьте это, и вы исправили свою проблему.
Тем не менее, ОС будет закрывать приложения, когда память начнет сокращаться. Фоновые приложения обычно идут первыми, но много раз, если утечка достаточно серьезна, период времени между тем, когда фоновые приложения завершаются, и время, когда запущенное приложение также завершается, может быть коротким.