Жонглирование нескольких контроллеров UINavigationController с помощью делегата приложения и обеспечение правильного освобождения UINavigationController - PullRequest
7 голосов
/ 20 ноября 2010

У меня есть приложение, которое использует два UINavigationControllers - один для системы меню и один для реальной игры. Общий UINavigationController объявлен в моем appDelegate. Когда приложение загружается, оно загружает меню или UINavigationController в игре. И, конечно, игрок может перемещаться между ними.

При переходе из меню в игру я создаю новый UINavigationController и представляю его следующим образом:

    GameViewController *rootController = [[GameViewController alloc] init];
     UINavigationController *newNavController = [[UINavigationController alloc] initWithRootViewController:rootController];
     [rootController release]; 
     newNavController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
     [self presentModalViewController:newNavController animated:YES];
[newNavController release];

Однако я заметил, что когда я это делаю, viewController в меню никогда не вызывает dealloc. Предположительно, потому что до сих пор есть упоминание о чем-то, что поддерживает это. Я обнаружил, что когда я явно устанавливаю UINavigationController делегата приложения на новый контроллер навигации (перед выпуском нового navController) он открывает меню. Я делаю это следующим образом:

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 
 appDelegate.navController = newNavController;
 [newNavController release];

Это хорошая практика? Однако я обнаружил, что при переходе от игры к меню, та же самая хитрость не работает. То есть

MainMenuViewController *menuViewController = [[MainMenuViewController alloc] init]; 
 UINavigationController *newNavController = [[UINavigationController alloc] initWithRootViewController:menuViewController];
 [menuViewController release];
 newNavController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
 [self presentModalViewController:newNavController animated:YES];

 //Setting the appDelegate's navController to the new navController allows the menu to dealloc. 
 //This must happen AFTER the newNavController has been loaded. 
 MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 
 appDelegate.navController = newNavController;
 [newNavController release];

никогда не вызывайте dealloc на главном ViewController игры. И когда я снова возвращаюсь к игре, основной ViewController меню также больше не выпускается.

Я что-то упускаю при манипулировании UINavigationControllers?

Спасибо,

Michael

РЕДАКТИРОВАТЬ: С тех пор я понял, что причина, по которой основной ViewController в моей игре не был отменен, заключалась в том, что у меня есть некоторые NSTimers, которые я не аннулировал! Тем не менее, мне все еще любопытно узнать, верен ли мой вышеприведенный подход, и что явное переопределение navController в делегате приложения является правильным способом разрешить различным UINavigationController обрабатывать :): 1020 *

1 Ответ

8 голосов
/ 09 декабря 2010

Сделай свою жизнь проще.Используйте один UINavigationController и поддерживайте два отдельных стека View Controller, которые являются просто массивами UIViewControllers.Вы можете использовать [UINavigationController setViewControllers:animated:], чтобы просто поменять стеки и оставить навигатор на месте.Используйте UINavigationController.viewControllers, чтобы удержать текущий стек перед его заменой.Это примерно в 14,3 миллиарда раз проще и чище, чем справляться со всеми капризами нескольких навигационных контроллеров.

...