2009-10-26 2 views
3

Корневой вопрос: «Сколько UIViewControllers вы можете нажать на стек навигации?» не вызывая предупреждения о памяти или получения прерывания сторожевого таймера.iPhone - UINavigationController, виды повторного использования?

Предположим, у меня есть приложение, которое представляет собой базу данных для трех объектов, каждая из которых может иметь отношения с каким-либо другим объектом, а связь показана на UIViewController. Пользователи могут следить за этими отношениями, и каждый из них отображает новый контроллер. Если объекты A, B и C и A-> B-> C-> B-> C-> A, то каждый вид просмотра находится в стеке дважды , Я понимаю, как нажать и поп, как вернуться к определенному контроллеру, и я думаю, а не просто расширить навигационный стек на неопределенный срок, лучше всего будет повторно использовать контроллер представления в стеке навигации.

Чтобы сделать это, каждый раз, когда мне нужен FirstEntityViewController, я мог бы сканировать стек навигации, чтобы найти объект, где [self isKindOfClass:[FirstEntityViewController class]];, а затем вызвать методы, предназначенные для rejig этого представления для того, что я сейчас хочу видеть, - просто обновляя данные в том же что вы делаете при повторном использовании UITableViewCell.

Это нормально, за исключением эффекта, который может иметь навигационный контроллер. Если я использую UINavigationController:popToViewController:animated:, я думаю, что он откажется от всего, что я вижу, включая представление, которое пользователь ожидает найти, нажав «Назад» на панели навигации. Таким образом, пользователь забирает отношения, отступает назад и идет «да?».

Если я удаляю соответствующий контроллер из стека навигации, а затем вставляю его в верхнюю часть стека, то поведение обратной связи остается в силе, пока пользователь не вернется к экземпляру FirstEntityViewController, который был перемещен или иначе навигация будет казаться непоследовательной.

Правильное решение для удаления контроллера из стека и каким-то образом удерживать место в стеке, чтобы при повторном использовании контроллера он мог быть заменен обратно туда, откуда он появился? Должен ли я поддерживать собственный список видов вида и отображения данных, чтобы при появлении я мог заменить вид под видом, который должен появиться, чтобы оставаться на шаг впереди назад?

Или это просто слишком сложно? Не стоит ли даже беспокоиться об этой ситуации, потому что ОС повторно использует большую часть контроллеров представлений так же, как UITableViewCells повторно используется, и нет реального влияния на память или производительность при использовании 50-футового навигационного стека?

+0

Похоже, есть два вопроса: 1) сколько вещей может быть в стеке, и 2) может ли данная вещь быть в стеке более одного раза? Правильно? –

+0

Вид. Определенно, сколько вещей может быть в стеке. Может ли данная вещь быть в стеке более одного раза, я достаточно уверен, что ответ да, меня просто беспокоит воздействие (т. Е. DidReceiveMemoryWarning) на его разрешение. Решение может состоять в том, чтобы дождаться этого предупреждения о памяти и затем начать поиск записей стека, чтобы убить, например, все до последнего «важного» представления. –

ответ

4

экземпляры ViewController остаются в стеке UINavigationController, но любой вид, кроме верхнего вида, может быть выгружен в любое время (контроллер вида уведомляется через сообщение viewDidUnload).

Другими словами, виды под видом сверху не обходят стороной и в конечном итоге будут выгружены в условиях низкой памяти, поэтому вам не придется пытаться повторно использовать контроллеры представлений.

+0

Что происходит с навигацией при разгрузке представлений - ссылка за отсутствующим видом и по-прежнему позволяет Назад или назад перестает быть опцией? –

+1

Нет. Когда пришло время для просмотра снова, оно загружается через сообщения loadView и viewDidLoad. Вы можете проверить это в симуляторе, смоделировав условие низкой памяти. – Darren

0

Последнее, что я проверил, вы не можете снова нажать на контроллер просмотра, который уже находится в стеке навигатора. Вам нужно будет создать новый диспетчер представлений и вставить его в стек, и каждая кнопка возврата выйдет из него. Лучшее, что вы можете сделать, это сделать кеш-контроллеры и использовать их по мере необходимости - если они выскочили из стека navcontroller. Но он, вероятно, не будет покупать вас много благодаря экономии памяти.

UITableViews немного отличаются тем, что в любое время доступно только относительно небольшое количество ячеек, и как только ячейка переходит на экран, она удаляется и возвращается обратно в пул. Если вы можете гарантировать, что maxdepth вашей цепочки зафиксирован, вы можете вытащить аналогичную схему окон. Если нет, вам, возможно, придется придерживаться глубокого понимания и проявлять бдительность в отношении освобождения памяти, как только сможете.