2009-06-02 3 views
12

Я столкнулся с ситуацией, которая, как представляется, предполагает иное. В следующем фрагменте кода, если я удаляю строку: self.navigationController = nav, представление корневого контроллера не будет отображаться, что указывает на то, что addSubview может фактически не сохранять представление, как было предложено в другом случае. Есть идеи?Действительно ли UUSiew's addSubview действительно сохраняет представление?

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]]; 

    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.testViewController]; 

    self.navigationController = nav; //<-- if this line is removed, test view won't show up 

    [window addSubview:nav.view]; 

    [nav release]; 
} 
+0

Ваш отмеченный ответ неправильный, по причинам, о которых я прокомментировал ниже. –

ответ

24

Эта линия:

[window addSubview:nav.view]; 

не добавляет вид на экран сразу. Он отображается ОС в некоторых будущих циклах запуска, возможно, в другом потоке. Мы не можем быть уверены в реальной реализации.

Именно поэтому Apple определяет методы делегатов, такие как viewDidAppear/viewWillAppear, в противном случае они нам не понадобятся, поскольку мы точно знаем, когда происходят эти события.

Кроме того, добавление подзаголовка, как вы сказали, действительно сохраняет вид. Однако NOT сохраняет контроллер вида или контроллер навигации. Поскольку контроллер навигации WILL сохранит все добавленные контроллеры просмотра, нам не нужно поддерживать их с помощью ivar.

Но ваша ссылка на контроллер навигации должна сохраняться за пределами метода. или в зависимости от вашего кода он может быть удален или потерян.

Таким образом, вы должны сохранить ссылку на навигационном контроллере с Ивар и установить его так:

self.navigationController = nav; 

Так что даже если nav.view содержит указатель на testViewController.view, приложение не имеет никакого отношения к навигационного контроллера и, соответственно, вида. Результатом является пустой экран.


Чтобы сделать это более очевидным, что это не проблема сохранения/выхода, вы на самом деле протекает следующим способом:

self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]]; 

Вам нужно autorelease, чтобы сбалансировать ваши сохраняющие/релизы по:

self.testViewController = [[[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]] autorelease]; 

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

+0

Хорошая работа Кори, очень похоже на объяснение, которое вы изложили. – Boon

+1

Неверно, что _view_ будет освобожден до того, как окно сохранит его. Если это так, вы увидите исключение, когда окно пытается получить доступ к освобожденному объекту. То, что получает освобожденный, - это навигационный контроллер, который не позволяет ему заполнять свой вид интересным контентом (например, панель навигации и корневой режим). –

+0

Подумав об этом, я добавил дополнительную информацию, которая также помогает объяснить, что вы видите. –

0

Это не похоже на вопрос о сохранении/выпуске. Вы не увидите, если вы закомментируете self.navigationController = nav;, потому что тогда в следующей строке [window addSubview:self.navigationController.view] ваше свойство self.navigationController не будет установлено. Вероятно, это ничто, или это сбой, но не может сказать точно без кода.

+0

Я обновил код до исходного кода, когда все не сработало, и я должен был ввести self.navigationController в вещи, чтобы держать ссылку на nav. Кроме того, то, что вы видите выше, - это весь код, который есть, и ничего больше. – Boon

+0

В объективе-c, начинаются ивары со значением 0. Итак, self.navigationController будет просто нулевым. –

2

Проблема, вероятно, заключается не в том, что вид не сохраняется, а в том, что контроллер не сохраняется.

Без этой строки:

self.navigationController = nav 

Ничто не сохраняя навигационный контроллер. Было бы странно, если бы взгляд перестал контролировать.

+0

Вид не «магически» связан с контроллером вида. Вид не просто умирает, потому что его контроллер просмотра умирает. Если представление сохранено в другом месте, оно будет абсолютно пережить любые контроллеры представлений. –

+0

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

+0

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

Смежные вопросы