iOS5, как "лениво" инициализировать контроллеры для панели вкладок? - PullRequest
2 голосов
/ 06 ноября 2011

У меня есть контроллер TabBar с до 9 контроллеров, каждый из которых имеет контроллер навигации.В настоящее время я выделяю и инициирую каждый из них в делегате приложения в

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{...}

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

Есть ли способ "ленивого" инициализации контроллеров представления , когда они впервые выбраны для панели вкладок?

Поможет ли мне разобраться с раскадровками для iOS5?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 06 ноября 2011

Как насчет определения ваших контроллеров как ленивых контроллеров?

Я имею в виду, если запуск приложения занимает некоторое время из-за инициализации девяти контроллеров представления, то это связано с тем, что контроллер фактически делает во время инициализации. Таким образом, вы можете заставить контроллер лениво инициализироваться в два этапа: один, когда вы добавляете все свои контроллеры в контроллер панели вкладок; во-вторых, когда вы выбираете конкретную вкладку, соответствующий контроллер инициализируется.

Я думаю, что это самый чистый подход.

В противном случае, я бы поставил на прямое использование UITabBar для управления им в своем собственном классе контроллеров панели вкладок.

В качестве последнего варианта я бы попытался на лету изменить содержимое контроллера панели вкладок, вызывая setViewControllers:animated: в соответствующее время в соответствии с некоторыми логическими схемами. Например, вы можете инициализировать контроллер панели вкладок только с 5 контроллерами представления в application:didFinishLaunchingWithOptions:, а затем добавить остальные в более поздний момент ...

Но мое реальное предложение - сделать контроллеры компонентов ленивыми ...

РЕДАКТИРОВАТЬ: после прочтения вашего вопроса в комментарии ...

Если вы попытаетесь выполнить отложенную инициализацию ваших контроллеров, я имею в виду следующее:

  1. вы инициализируете свои контроллеры (или UIKit будет при загрузке пера), вызывая [[... alloc] init ...]; это не меняется;

  2. метод init инициализирует контроллер до его состояния по умолчанию, такого как установка свойств и значений ivar, и не делает ничего более сложного;

  3. до отображения представления контроллера, вы завершаете его инициализацию, вызывая определенный метод; это выполнит часть «довольно много делегирования», которую я считаю длительной частью инициализации.

Извините, если разговор о "отложенной инициализации" вызвал неоднозначность между логической инициализацией компонента и содержанием метода init.

Что касается пункта 3, у вас есть несколько вариантов того, где завершить инициализацию.

Возможно, когда контроллер будет отображаться. В этом случае либо вы определяете -tabBarController:didSelectViewController: в делегате контроллера панели вкладок, либо используете viewWillAppear. Это даст вам самую ленивую инициализацию из всех, но, возможно, добавит некоторую задержку в тот момент, когда вы выберете вкладку до появления представления.

Еще лучше использовать viewDidLoad, что даст вам немного ленивую инициализацию; инициализация всех ваших контроллеров может произойти в какой-то момент времени, который вы не контролируете (конечно, до отображения представления), поэтому это может немного задержать события, но это не произойдет в applicationDidFinishLoading и будет более дружественным к пользовательскому интерфейсу, так как он будет контролироваться основным циклом. Определенно, первый вариант, чтобы попробовать. Также обратите внимание на описание viewDidLoad в справочнике UIViewController .

Наконец заметка об отдельной теме. Имейте в виду, что не все безопасно использовать UIKit из отдельного потока, поэтому будьте осторожны.

2 голосов
/ 07 ноября 2011

Чувствовал, как добавить быстрый .02 к этому вопросу.Процесс инициализации и загрузки UIViewController уже «ленив», как отмечали другие.Реальный вопрос в том, что вы делаете в своей инициализации, которая занимает так много времени?Даже загрузка представлений не должна занимать много времени, так как вы не хотите, чтобы пользователи ждали, когда коснитесь вкладки, прежде чем представление изменится.Я предлагаю следующее:

  1. В init сделайте как можно меньше.Цель init состоит в том, чтобы все независимые данные инициализировались и были готовы.Вы не должны загружать какие-либо виды здесь.

  2. В loadView или viewDidLoad создайте все свои виды / подпредставления.

  3. Только загрузкаданные, когда вам это нужно.Если вам это нужно в init, загрузите его туда.Если вы можете дождаться загрузки представлений, сделайте это в viewDidLoad.Если загрузка данных занимает много времени, загрузите его в фоновом режиме.

1 голос
/ 07 ноября 2011

В вашей реализации UIViewController создайте все ваши представления в методе

- (void)viewDidLoad

и избегайте создания представлений (или, что еще хуже, получения данных) в вашем методе init.

UITabBarController илиUINavigationController будет вызывать viewDidLoad по умолчанию lazy, то есть непосредственно перед тем, как пользователь его увидит.

...