0

Я использую Xcode 6.3, Objective-C.Создание ViewControllers с помощью раскадровки против alloc/init

В моей раскадровке я создаю UINavigationController. Затем я создаю UIViewController и назначаю его в качестве корневого контроллера UINavigationController. Затем я создаю второй UIViewController и подключаю его к первому UIViewController с помощью «ручного шоу».

Итак, у моей раскадровки есть UINavigationController и два UIViewControllers, все подключены. У меня также есть кнопка в первом UIViewController, у которой есть действие для отображения второго UIViewController (подробнее об этом немного).

Мой вопрос в том, что когда приложение запускается, все созданные контроллеры все однажды?

Основной вопрос, когда я нажмите кнопку, чтобы отобразить второе UIViewController, используя обычный [self.navigationController pushViewController:controller animated:YES], делает это второй UIViewController уже существует - в силе того, что было создано, когда раскадровка была загружена и проанализирована?

Или, прежде чем делать толкание, мне нужно сначала сделать [... alloc] init]?

Я знаю, что если вы создаете программно UIViewControllers, вам обязательно нужно будет сделать alloc и init. Но мне непонятно, нужен ли alloc/init, когда UIViewController s были «созданы» в раскадровке?

Тестирование соединения с использованием [self performSegueWithIdentifier...] похоже на работу: отображается второе UIViewController, и явное выделение/init не было выполнено. Поэтому мне кажется, что контроллер назначения создается (alloc/init) UIKit, когда выполняется segue. Вам не нужно делать эту часть.

Но если я хочу показать второй UIViewController с использованием подхода ...pushViewController:controller..., как бы я получил указатель на него? Массив из UIViewController s в UINavigationController имеет только один элемент, а не два - что имеет смысл: этот массив будет иметь ссылку второго контроллера, добавленную к нему, только когда он был вставлен в стек.

Итак, если бы я хотел сделать ...pushViewController:controller..., и если предположить, что второй UIViewController существует (потому что он был создан раскадровкой), как я могу получить указатель на него - в первом контроллере?

Или я должен сначала явно создать его с помощью «alloc/init», который, конечно, дает мне указатель?

Мне кажется, что если раскадровка создает все контроллеры, то ссылки на них должны где-то существовать.

И если это так, выполнение шага «alloc/init» на втором контроллере, когда он уже был создан раскадровкой, является избыточным, правильно?

Или, хотя я создал второй UIViewController в раскадровке, мне все еще нужно создать экземпляр с сообщением «alloc/init»?

Конечно, делать ручной переход к второму контроллеру не имеет смысла, потому что вы не пользуетесь UINavigationController, и это на самом деле избыточно.Итак, чтобы воспользоваться навигацией, вы должны использовать подход ...pushViewController:controller..., для которого требуется указатель на этот второй контроллер. Что, наивно, предлагает «alloc/init». Но опять же, я не понимаю, почему вам нужно явное создание экземпляра класса, когда раскадровка (если я правильно ее понимаю) сделала бы это для меня.

Я знаю, что выполнение «alloc/init» только создает объект; атрибуты не установлены. Для этого мне нужно будет instantiateViewControllerWithIdentifier. Но тогда я все еще создаю этот второй контроллер вручную, не так ли? Таким образом, раскадровка не создает их для меня во время выполнения?

Я знаю, что раскадровка вызывает initWithCoder, а затем awakeFromNib, предполагая, что раскадровка фактически создает эти объекты при запуске приложения. Но делает ли это так, что, конечно, когда приложение работает, или мне все еще нужно делать что-то вручную, явно? То, что я до сих пор, является указателем на второй контроллер для использования в push и где/как я могу получить этот указатель.

Извините за длинный вопрос: я просто хочу быть более четким из того, что я понимаю до сих пор и в чем мой вопрос. Да, я iOS n00b - вот почему я обращаюсь за экспертной помощью. За что я вас очень благодарю.

ответ

2

Если вы создали UIViewControllers в раскадровке, они, кажется, инициализируются сразу. Вам не нужно выделять/init, если вы используете раскадровки. Используйте segues. Если вы не хотите использовать перетекает затем использовать:

// Здесь экземпляр контроллера вид программно

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"View controller storyboard id"]; 

Set раскадровку ID в раскадровке (Удостоверение инспектора) :)

Тогда просто добавить Нажимаем ViewController:

[self.navigationController pushViewController:controller animated:YES]; 

Или, если вы не используете навигацию контроллера:

[self presentViewController:controller animated:YES completion:nil]; 
+0

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

+0

Используя этот код, после запуска нового viewController, self.navigationcontroller является nil –

1

Мой вопрос в том, что, когда приложение запускается, все контроллеры созданы все сразу?

Нет, создается только начальный контроллер (один со стрелкой в ​​раскадровке). Если это Navigation controller, будет создан его корневой контроллер.

Или, прежде чем делать push, мне нужно сначала выполнить [... alloc] init]?

Да, у вас должно быть alloc initViewController перед тем, как вставить его в стек навигационной панели. Он еще не создан.

Под капотом, если вы используете раскадровку, он вызовет initWithCoder:, чтобы запустить ваш контроллер. Затем вы можете установить его свойства с помощью метода prepareForSegue:.

Если вы используете методы кодирования, просто alloc init контроллер, установите его свойства и pushToViewController

Простой, правильно?

Как я могу получить указатель на него - в первом контроллере?

Я., с помощью метода prepareForSegue:, новый контроллер segue.destinationViewController

...

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

+0

Спасибо. Я все еще не уверен, почему, если ViewController существует в раскадровке, почему он не будет создан, когда iOS загрузит XML-файл раскадровки, проанализирует его и создаст все объявленные в нем объекты. Мне кажется, что если вы iOS, и вы просто нанесли вред XML-файлу раскадровки, вы просто прокрутите все теги и, таким образом, создадите все контроллеры сразу. Теперь это НЕ сказать, что эти контроллеры будут отображаться. Но они должны быть созданы. Но вы дали мне некоторые идеи, с которыми я могу экспериментировать, поэтому я благодарю вас за это! – Lew

+0

Нет, Лью. Они не будут созданы, потому что это не эффективно. Вы говорите о создании сотен 'UIView' при запуске приложения, и это займет много времени. Кроме того, эти контроллеры еще не готовы к использованию (у них есть только представления, а не данные, поэтому зачем их создавать?). Кроме того, некоторые контроллеры и представления еще не созданы (потому что мне нравится кодировать мои представления, а не раскадровку), поэтому я должен проверить, существует ли это уже или нет, правильно? ... Это будет хаотично, если раскадровка работает как как вы думаете, TBH. –

+0

ОК, конечно, что вы говорите, имеет смысл. Спасибо за разъяснение - оцените! – Lew

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