Когда мне нужно позвонить - [UIViewController initWithNibName: bundle:]? - PullRequest
6 голосов
/ 26 мая 2011

В посте Использование initWithNibName абсолютно ничего не меняет , он показывает два использования одного и того же определения View Nib, в первом случае он просто вызывает alloc / init, а во втором он указывает initWithNibName.

Итак, хотя это всегда работает:

MyViewController *vctrlr = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; [self.navigationController pushViewController:vctrlr animated:YES]; [vctrlr release];

Следующее работает для всех контроллеров представления, которые я унаследовал, но не мой!

TheirViewController *vctrlr = [[TheirViewController alloc] init]; [self.navigationController pushViewController:vctrlr animated:YES]; [vctrlr release];

Впервые в программировании на iOS, я унаследовал некоторый код.Все представления контроллеров представления определены в IB, но было несовместимое распределение / инициализация создания этих контроллеров представления.Я создал новый View Controller и XIB, но он не работает, если я не использую initWithNibName (он падает, когда я помещаю контроллер представления в Nav Controller).Я не могу сказать, чем мой контроллер просмотра отличается от других ... какие-либо подсказки?Мне удалось удалить использование initNibName для всех других контроллеров представления в приложении, кроме моего.

Ответы [ 2 ]

1 голос
/ 28 сентября 2013

Вы можете передать любое имя строки на initWithNibName:.Вы не ограничены только вызовом initWithNibName:@"MyClassName", когда ваш класс называется MyClassName.Это может быть initWithNibName:@"MyClassNameAlternateLayout".

. Это становится полезным, если вам нужно загрузить другое перо в зависимости от того, что приложение должно делать.Хотя я стараюсь по возможности использовать одно перо для каждого контроллера представления для каждой категории устройств (iPhone или iPad), чтобы упростить разработку и обслуживание, я мог понять, захочет ли разработчик иногда предоставлять другую компоновку или другую функциональность.

Другим важным моментом является то, что initWithNibName: bundle: является назначенным инициализатором для UIViewController.Когда вы звоните -[[UIViewController alloc] init], то initWithNibName:bundle: вызывается за кадром.Вы можете проверить это с помощью символической точки останова.Другими словами, если вы просто хотите поведение по умолчанию, ожидается, что вы можете вызвать -[[UIViewController alloc] init], и назначенный инициализатор будет вызван неявно.

Если, однако, вы вызываете -[[UIViewController alloc] init] и не получаетеожидаемое поведение, вероятно, ваш подкласс UIViewController неправильно реализовал - (id)init.Реализация должна выглядеть как один из этих двух примеров:

- (id)init
{
    self = [super init];
    if (self) {
        // custom initialization
    }
    return self;
}

или

- (id)init
{
    NSString *aNibName = @"WhateverYouWant";
    NSBundle *aBundle = [NSBundle mainBundle]; // or whatever bundle you want
    self = [self initWithNibName:aNibName bundle:aBundle];
    if (self) {
        // custom initialization
    }
    return self;
}
0 голосов
/ 08 июня 2016
If you want to work following code:

MyViewController *vctrlr = [[MyViewController alloc] inil];
[self.navigationController pushViewController:vctrlr animated:YES];

Then you should implement following both methods in MyViewController:

- (id)init
{
   self = [super initWithNibName:@"MyViewController" bundle:nil];
   if (self != nil)
   {
       // Do initialization if needed
   }
   return self;
}
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
    NSAssert(NO, @"Init with nib");
    return nil;
}
...