iPhone SDK: в чем разница между loadView и viewDidLoad? - PullRequest
135 голосов
/ 22 февраля 2009

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

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

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

Спасибо!

Ответы [ 7 ]

199 голосов
/ 22 февраля 2009

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

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

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

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

Обычный способ программно построить представление в -loadView, как продемонстрировано в примерах Apple, предшествовавших созданию интерфейса, выглядит следующим образом:

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

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

43 голосов
/ 22 февраля 2009

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

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

13 голосов
/ 21 августа 2013
viewDidLoad()

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

LoadView()

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

11 голосов
/ 22 февраля 2009

Просто добавьте несколько примеров кода, чтобы продемонстрировать, что сказал 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];
}
2 голосов
/ 02 марта 2011

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

- (void) loadView {
[super loadview];

// init code here...

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

}
1 голос
/ 04 декабря 2013

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

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

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

[super loadView];

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

1 голос
/ 19 июля 2012

Самый простой способ использовать 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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...