0

Я уже читал кучу ответов на SO, но я немного смущен.View Controllers, Injection Dependency и init/viewDidLoad

У меня есть подкласс контроллера панели вкладок, который я создал, и в его viewDidLoad я создаю каждый из контроллеров представления. Тем не менее, у меня есть зависимость от того, что я перехожу в родительский элемент и, в свою очередь, в контроллер просмотра для каждой вкладки. Я передаю эту зависимость с помощью специального метода инициализации (NS_DESIGNATED_INITIALIZER, объявленного для него в заголовке). Однако, похоже, что [super init] запускает viewDidLoad напрямую, поэтому зависимость не установлена ​​должным образом при создании других контроллеров представлений.

Вот мой метод пользовательских инициализации:

- (instancetype)initWithSession:(T2Session *)session 
{ 
    self = [super init]; 

    if (self) { 
     _session = session; 
    } 

    return self; 
} 

Я хотел session быть установлены к тому времени я создаю контроллеры просмотра, но я вроде путать о том, что лучший способ сделать это , Любые советы очень ценятся. Заранее спасибо!

+0

Вызов init не вызывает вызов viewDidLoad. Метод viewDidLoad вызывается для контроллера на первой вкладке, потому что контроллер панели вкладок добавляет представление контроллера в его представление. Ни один из других контроллеров не должен иметь viewDidLoad, пока вы не нажмете на их вкладку. – rdelmar

+0

Хм ... Я установил точку останова в viewDidLoad моего контроллера панели вкладок, а трассировка стека указала прямо на мою строку 'self = [super init];' ... ... – Mason

+0

Инициирование в любом контроллере не должно приводить непосредственно к представлению загружается. В случае контроллера панели вкладок его представление загружается (каким-то образом) системой, потому что это rootViewController окна, и это приводит к вызову viewDidLoad. – rdelmar

ответ

1

Раньше я сталкивался с этой ситуацией.
Вы, наверное, сидели (как и я), желая, чтобы viewDidLoad так скоро не вызвали.

Во всяком случае, это то, что я остановился на:

- (instancetype)initWithSession:(T2Session *)session { 

    if (self = [super init]) { 
     self.session = session; 
    } 

    return self; 
} 

- (void)setSession:(T2Session *)session { 
    _session = session; 

    ... call the setup methods here, instead of viewDidLoad 
} 

Сначала я думал, что это нарушает золотое правило из не вызывая self.xxxx внутри инициализатора.
Однако, я думаю, что это правило действительно актуально при вызове методов на IBOutlets, которые еще не были подключены.
В этом случае T2Session *session не является выходным отверстием.

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

T2Session *session = ..... 

MYTabBarController *tabBarController = [[MYTabBarController alloc] init]; 
[tabBarController setSession:session]; 

Это только мои мысли, надеюсь, что это поможет.

+0

также убедитесь, что вы вызываете _session = session в начале setSession: method – MDMonty

+0

Awesome, спасибо за совет! Все еще ничего не сделал по этому поводу, но я буду думать об этом больше. – Mason