IPhone SDK: в чем разница между loadView и viewDidLoad?

При работе с представлениями и диспетчерами представлений в приложении для iPhone можно ли объяснить разницу между loadView и viewDidLoad?

Мой личный контекст - это то, что я строю все свои представления из кода, я не использую и не буду использовать Interface Builder, если это имеет значение.

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

Спасибо!

Ответ 1

Я могу догадаться, что может быть проблемой здесь, потому что я это сделал:

Я обнаружил, что часто, когда я добавляю код init для loadView, я получаю бесконечную трассировку стека

Не читайте self.view в -loadView.. Только установите его, не получите.

Атрибут свойства self.view вызывает -loadView, если представление в настоящее время не загружено. Там ваша бесконечная рекурсия.

Обычный способ создания представления программно в -loadView, как показано в примерах Apple pre-Interface-Builder, выглядит примерно так:

UIView *view = [[UIView alloc] init...];
...
[view addSubview:whatever];
[view addSubview:whatever2];
...
self.view = view;
[view release];

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

Ответ 2

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

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

Ответ 3

viewDidLoad()

следует использовать, когда вы загружаете свое представление из NIB и хотите выполнить любую настройку после запуска

LoadView()

следует использовать, если вы хотите создать свой вид программно (без использования Interface Builder)

Ответ 4

Просто добавив некоторые примеры кода, чтобы продемонстрировать, что сказал NilObject:

- (void)loadView
{
    // create and configure the table view
    myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped];   
    myTableView.delegate = self;
    myTableView.dataSource = self;
    myTableView.scrollEnabled = NO;
    self.view = myTableView;

    self.view.autoresizesSubviews = YES;
}

- (void)viewDidLoad 
{
  self.title = @"Create group";

  // Right menu bar button is to Save
  UIBarButtonItem *saveButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save)];
  self.navigationItem.rightBarButtonItem = saveButtonItem;
  [saveButtonItem release];
}

Ответ 5

Чтобы предотвратить бесконечный цикл, когда вы читаете self.view, вызовите супер-реализацию класса при загрузке представления. Супер-реализация выделит вам новый UIView.

- (void) loadView {
[super loadview];

// init code here...

[self.view addSubView:mySubview1]; //etc..

}

Ответ 6

Самый простой способ использования loadView - создать некоторый тип контроллера базового представления, например MyBaseViewController, который является подклассом UIViewController. В нем метод loadView создает представление таким образом:

-(void) loadView {
    if ([self viewFromNib]) {
        self.view = [self viewFromNib];
    } else {
        self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    }
    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    self.view.backgroundColor = [UIColor whiteColor];
}

И когда вам нужно создать какой-нибудь контроллер вида, вы просто используете подкласс MyBaseViewController, а в нем контроллер loadView вы просто вызываете [super loadView], как этот

//sucblass loadView
-(void) loadView {
    [super loadView];

    //rest of code like this..
    UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];
    [self.view addSubview:myLabel];
    [myLabel release];
}

Ответ 7

loadView() вызывается, когда вашему контроллеру предлагается создать его self.view. Вы можете сделать это самостоятельно, как

self.view = [UIView alloc] init...];

Или ваш родительский класс контроллера UIController уже имеет имя метода -loadView(), которое инициализирует ваш self.view в пустой вид. Затем вы можете позвонить

[super loadView];

Я действительно рекомендую второй подход, поскольку он поощряет наследование. Только если ваш контроллер просмотра напрямую не унаследован от UIViewController.

Ответ 8

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

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