Почему UILabel не инициализируется?

Код взят из Stanford CS193p. Я добавил NSLog, чтобы проверить это. Метка, кажется, не инициализируется. Есть идеи?

@interface AskerViewController() <UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UILabel *questionLabel;
@property (weak, nonatomic) NSString *question;
@end


@implementation AskerViewController
@synthesize questionLabel = _questionLabel;
@synthesize question = _question;


 - (void)setQuestion:(NSString *)question
{
    _question = question;
    self.questionLabel.text = question;
    NSLog(@"label is %@", self.questionLabel);
}

@end

Результат NSLog:

2012-07-31 01:56:45.177 Kitchen Sink[23931:f803] label is (null)

person Philip007    schedule 30.07.2012    source источник
comment
Геттер и сеттер чего? Им звонят, когда им звонят, вам нужно предоставить больше информации, иначе на этот вопрос нельзя будет ответить.   -  person jrturton    schedule 30.07.2012
comment
Ты прав. Я пересматриваю пост и добавляю код, чтобы конкретизировать вопрос.   -  person Philip007    schedule 30.07.2012
comment
Ваш UILabel подключен/связан с questionLabel?   -  person Karoly S    schedule 30.07.2012
comment
setQuestion: не инициализирует метку. Он только устанавливает текст. Инициализирована ли метка? Розетка подключена в Interface Builder?   -  person Adam    schedule 30.07.2012
comment
Положительно, questionLabel подключен к контроллеру через раскадровку.   -  person Philip007    schedule 30.07.2012
comment
Как инициировать UILabel? Не могли бы вы дать мне строку кода и сказать, куда я должен ее вставить?   -  person Philip007    schedule 30.07.2012


Ответы (1)


Вероятно, вы устанавливаете свойство строки вопроса перед отображением контроллера представления, предположительно, в prepareForSegue:? На данный момент представление не загружено, и свойство метки по-прежнему равно нулю.

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

Если вы устанавливаете свойства до вызова viewDidLoad, ожидается, что метка равна нулю. И если вы устанавливаете свойства из prepareForSegue, представление еще не будет загружено. Контроллер представления не будет загружать свое представление и подпредставления, пока ему не потребуется отобразить их на экране, и этого не произойдет, пока не будет выполнен переход - и, как вы можете догадаться, prepareForSegue выполняется до выполнения перехода.

person jrturton    schedule 30.07.2012
comment
Не выделяйте/инициируйте метку, если она есть в вашей раскадровке. Вот откуда будет исходить ваш ярлык. Если вы устанавливаете свойства до вызова viewDidLoad, ожидается, что метка равна нулю. И если вы устанавливаете свойства из prepareForSegue, представление еще не будет загружено. Контроллер представления не будет загружать свое представление и подпредставления, пока ему не потребуется отобразить их на экране, и этого не произойдет, пока не будет выполнен переход - и, как вы можете догадаться, prepareForSegue выполняется до выполнения перехода. Это превратилось в длинный комментарий, я собираюсь добавить его к своему ответу... - person jrturton; 31.07.2012
comment
Я понимаю. Я помещаю что-то вроде segue.destinationViewController.question в prepareForSegue, который вызывает setQuestion, который, в свою очередь, пытается получить доступ к questionLabel, который еще не загружен во время перехода в качестве подпредставления в иерархии представлений целевого контроллера представлений. Вот почему NSLog возвращает ноль. - person Philip007; 31.07.2012
comment
Абсолютно верно. Вы по-прежнему должны хранить этот код в setQuestion, потому что вы можете снова задать вопрос, пока представление все еще загружено, вам просто нужен этот дополнительный бит в viewDidLoad. - person jrturton; 31.07.2012
comment
Удивительно! Я думаю о той же проблеме: зачем хранить код self.questionLabel.text = question; в setQuestion. Что делать, если у меня нет необходимости задавать вопрос снова? Поскольку логический поток заключается в том, чтобы разрешить представленному контроллеру представления задавать вопрос, который использует prepareForSegue для отправки строки вопроса представленному контроллеру представления. Переход устанавливает представленный контроллер. Текст метки устанавливается в viewDidLoad. Я не хочу, чтобы ярлык был установлен каким-либо другим способом. Итак, с точки зрения безопасности, я должен просто удалить код, а значит, и пользовательский сеттер (setQuestion) вместе? - person Philip007; 31.07.2012
comment
Если вы всегда будете использовать его таким образом, то да, это будет хорошо. - person jrturton; 31.07.2012