2012-06-20 2 views
0

У меня есть приложение, которое основано на UINavigationController. Существует экран меню с кнопками, которые переходят (нажимают на стек навигационного контроллера) на один из 9 других «подэкранов». Ни один из этих субэкранов не переходит на любой другой экран. Когда пользователь выполнит ввод данных на «субэкран», они могут нажать кнопку «Готово», которая вернется к исходному экрану меню. (Если у вас возникли трудности с изображением этого, представьте себе дерево, подобное раскадровке, где есть один корневой ViewController, а затем 9 leaf viewControllers).ViewDidLoad и UINavigationController в iOS?

Хорошо, поэтому с этой настройкой у меня есть несколько вопросов о том, как работает viewDidLoad.

~ Во-первых, это viewDidLoad, который должен быть вызван каждый раз, когда мы переходим на дополнительный экран. Например, предположим, что я перехожу с экрана меню на субэкран «B», обратно на экран меню, а затем обратно на субэкран «B». Должен ли метод B viewDidLoad вызываться дважды? Если нет, то зачем мне звонить дважды?

~ Во-вторых, если предположить, что он будет вызван каждый раз, что делать, если у меня много длинных операций, которые нужно выполнять ровно один раз для каждого подэкрана? Куда я должен поместить их (если я поместил их в viewDidLoad, это произошло бы несколько раз, если бы пользователь продолжал идти туда и обратно между этой страницей и меню)?

ответ

1

Чтобы ответить на ваши вопросы:

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

  2. Там может быть множество способов обращения с этим типом ситуации. Трудно сказать, что правильно для вас, не видя точно, что вы пытаетесь сделать. Один из способов - создать singleton object, который обрабатывает обработку. Причина, по которой это может быть лучше, чем обработка его в вашем UIViewController, заключается в том, что singleton может жить на протяжении всего срока службы приложения, тогда как UIViewControllers обычно имеют относительно короткий срок службы. Объекты Singleton могут быть созданы только один раз, и они могут управлять любыми операциями и данными, которые вам нужно сохранить в течение всего срока службы вашего приложения.

+0

viewDidLoad будет вызываться только один раз для каждого раза, когда представление было «init» ed не каждый раз, когда оно добавлено в стек. – sunrize920

+0

В своем ответе я объяснил, что «каждый раз, когда B выскочит из стека, выпущенный, и каждый раз, когда вы идете в B, создается новый экземпляр B. «aka init/viewDidLoad будет вызываться каждый раз, когда вы посещаете B. –

+0

Я бы не сказал, что он обычно выпущен. viewDidUnload вызывается только на контроллере представления, когда свойство вида выпущено/установлено в nil, и это обычно происходит только в том случае, если приложение получает предупреждение о памяти. – sunrize920

0

viewWillAppear вызывается каждый раз, когда отображается представление. viewDidLoad ТОЛЬКО вызывается, когда создается представление - так, например, после того, как контроллер вида initFromNibNamed вызывается при обращении к виду. viewWillAppear вызывается в любое время, когда ваш контроллер просмотра не был в поле зрения, но появляется в поле зрения - поэтому, когда ваш контроллер просмотра нажат, вызывается viewWillAppear. Поэтому вы можете подумать, что ваш viewDidLoad вызывается дважды, но на самом деле это, вероятно, нет. Поэтому вы должны поместить методы в viewDidLoad. Что вы делаете, это занимает много времени?

0

1. viewDidLoad вызывается при загрузке представления и вызывается viewWillAppear, когда вид становится видимым.

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

Что вы могли бы сделать что-то вроде этого:

В вашем «корень» ViewController класс, объявить каждый «лист» ViewController в качестве члена, позволяет сказать, что они называются leafController1, leafController2 и т.д., и создавать сохраняющие-свойства их.

@interface YourRootViewController : UIViewController { 
    LeafController1Class *leafController1; 
    LeafController2Class *leafController2; 
    // ... 
} 

@property (nonatomic, retain) LeafController1Class *leafController1; 
@property (nonatomic, retain) LeafController2Class *leafController2; 

// ... 

@end 

В ViewDidLoad вашей верхней ViewController, инициализировать все листовые-контроллеры с помощью «initWithNibName» и т.д. (или все, что вы делаете, чтобы создать их). Сохраните свои экземпляры, как так:

self.leafController1 = [[[LeafController1Class alloc] initWithNibName:@"LeafController1NibName" bundle:nil] autorelease]; 

Когда пользователь нажимает на кнопку, нажать правильный лист на navigationcontroller:

[myNavigationController pushViewController:leafController1 animated:YES]; 

Когда вы поп контроллеры листьев теперь они будут храниться в памяти, так как вы сохранили их. Таким образом, ваш viewDidLoad будет вызываться только один раз для каждого листа, до тех пор, пока вы всегда нажимаете на тот же самый элемент управления viewController на свой навигационный контроллер.

2. Тяжелый код, связанный с представлением, должен быть выполнен, когда представление загружено, то есть вызвано viewDidLoad. Но также может быть хорошей идеей держать другие классы, которые содержат информацию о вашем приложении, которые не являются диспетчерами просмотра и отделены от пользовательского интерфейса. Тяжелые вычисления лучше делать в фоновом режиме или когда приложение загружается в первый раз.

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