делегат = [[UIApplication sharedApplication] делегат]; не работает в init: только viewDidLoad

Я использую делегата для хранения данных для своего приложения. У меня есть tabviewcontroller с контроллером навигации в качестве первого контроллера представления. Когда я устанавливаю делегата, используя

delegate = [[UIApplication sharedApplication] delegate]; 

делегат имеет значение NULL вне метода инициализации.
Однако он отлично работает, когда помещается в viewDidLoad. Есть идеи, почему это могло быть?

ОБНОВИТЬ

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        delegate = [[UIApplication sharedApplication] delegate];
    }
    return self;
}

person James    schedule 05.07.2011    source источник
comment
Какие методы инициализации вы отменяете? Тот, который вызывается, зависит от того, как создан контроллер.   -  person Caleb    schedule 05.07.2011
comment
- (id) initWithNibName: (NSString *) nibNameOrNil bundle: (NSBundle *) nibBundleOrNil Кроме того, он был вызван, и делегат установлен внутри метода инициализации, однако, если я попытаюсь получить доступ к делегату вне метода инициализации (например, , в viewDidLoad), тогда делегат равен нулю   -  person James    schedule 05.07.2011
comment
Но работает ли он внутри метода инициализации? Разве это не ноль?   -  person akashivskyy    schedule 05.07.2011
comment
Внутри метода инициализации я могу получить доступ к делегату, да, но не за его пределами.   -  person James    schedule 05.07.2011
comment
Можете показать еще код? Вы получаете предупреждения? Что означает delegate в коде, который вы показываете: переменная экземпляра или локальная переменная?   -  person Caleb    schedule 05.07.2011
comment
глобальная переменная экземпляра - это терминологическое противоречие. Покажите объявление delegate и подумайте о том, чтобы показать весь метод, в котором находится рассматриваемый код.   -  person Caleb    schedule 05.07.2011
comment
Ваша переменная delegate имеет локальную область видимости для вашего метода инициализации. Вы не назначаете его чему-либо с большей областью действия или более длительным сроком службы, чем это. По крайней мере, это предположение, которое я сделал из кода, который вы показали - вы не показали нам, где вы объявляете delegate где-либо, кроме как прямо здесь.   -  person Dan Ray    schedule 05.07.2011
comment
В заголовочном файле я это объявляю   -  person James    schedule 05.07.2011


Ответы (3)


Находится ли этот контроллер представления в вашем файле MainWindow.xib (или как там называется основной .xib в вашем проекте)? Если это так, делегат приложения, вероятно, также создается при загрузке этого файла, а делегат приложения, вероятно, равен нулю во время создания вашего контроллера представления. Если делегат вашего приложения имеет ссылку на этот контроллер представления, установите его в качестве делегата контроллера представления в -applicationDidFinishLoadin:withOptions: или просто подключите делегат приложения к выходу -delegate контроллера представления в файле .xib.

person Caleb    schedule 05.07.2011
comment
Это не MainWindow.xib. Я создал отдельный класс tabBarViewController, внутри которого есть панель вкладок. Также существует отдельный UIViewcontroller для этого конкретного контроллера просмотра. - person James; 05.07.2011
comment
Тем не менее, если рассматриваемый контроллер представления создается при запуске приложения, делегат приложения еще не может быть установлен. Если вы прервете строку, в которой пытаетесь его назначить, действительно ли вы получите законный указатель на делегата приложения? - person Caleb; 05.07.2011
comment
Контроллер представления не создается, пока перед ним не будет нажата кнопка на экране входа в систему. И да, в методе init я получаю законный указатель на делегата, я даже могу получить доступ к его значениям. Однако после завершения метода инициализации я больше не могу получить доступ к делегату. - person James; 05.07.2011

Вы не должны использовать метод -init. Иногда его не называют. Используйте эти методы для дополнительной инициализации:

- (void)viewDidLoad {
    [super viewDidLoad];
    // do something
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // do something
}
person akashivskyy    schedule 05.07.2011
comment
Вы можете это оправдать? Нет ничего плохого в инициализации вашего контроллера представления в его методах инициализации; просто представление контроллера в этот момент не загружено, поэтому инициализацию, зависящую от представления, следует отложить до -viewDidLoad. - person Caleb; 05.07.2011
comment
Да, я знаю, что это работает, если я использую viewDidLoad, но я не думаю, что это лучшая практика. Также в этой ситуации вызывается init - person James; 05.07.2011
comment
Хорошо, с моей стороны было глупо не осознавать раньше, но если я установлю значение глобальной тестовой строки, я даже не смогу получить доступ к этому значению вне init. Происходит что-то очень странное - person James; 05.07.2011

Файл пера вызывал метод initWithCoder, а не init.

person James    schedule 07.07.2011