Я только что получил ту же проблему в последнее время. Но когда я отлаживаю шаг за шагом, я нахожу возможную причину. (Извините, я также новичок в Objective C, поэтому моё следующее объяснение может быть не таким точным и профессиональным ... Мой предыдущий опыт в основном был веб-разработкой.)
Если вы установите точку останова сразу после линии, которую вы вызываете
testViewController *viewController = segue.destinationViewController;
когда вы создадите и запустите проект, вы обнаружите, что свойство UITextField в destinationViewController не выделяется и не инициируется (память 0x0) в точке останова. Между тем свойство NSString уже выделено и инициализировано (поэтому вы можете установить его значение).
Я думаю, что UITextfield является дочерним представлением, поэтому оно инициируется только тогда, когда инициируется его родительское представление (целевое представление). Но NSString - это свойство, которое не связано ни с каким представлением, поэтому оно выделяется и инициируется контроллером представления, который его объявляет.
Когда я провожу дальнейшую проверку этого, я нахожу очень интересную вещь: второе представление загружается во время прогонов - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
. Я делаю тестовый код, как показано ниже:
В первом виде .m файл контроллера:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(@"1. %@, %@",[segue identifier],segue.destinationViewController);
Scene2Controller *scene2ViewController = [segue destinationViewController];
[txtScene2 resignFirstResponder];
NSLog(@"2. scene2ViewController: %@", scene2ViewController);
NSLog(@"3. txtScene1: %@; passValue: %@", [scene2ViewController txtScene1], scene2ViewController.passValue);
NSLog(@"4. View2: %@; passValue: %@", [scene2ViewController view], scene2ViewController.passValue);
NSLog(@"5. txtScene1: %@; passValue: %@", [scene2ViewController txtScene1], scene2ViewController.passValue);
//txtScene1 is the UITextfield property I declared in the second view controller
//txtScene2 is the UITextfield property I declared in the first view controller
//passValue is the NSString property I declared in the second view controller
}
Во втором представлении контроллера .m файл:
- (void)viewDidLoad
{
NSLog(@"6. txtScene1: %@; passValue: %@", txtScene1,passValue);
[super viewDidLoad];
}
Заметил, что я добавляю порядковые номера перед сообщениями NSLog. Я обнаружил, что окончательная последовательность результатов журнала была 1,2,3,6,4,5, а не 1,2,3,4,5,6. И в журнале 3 результат txtScene1 был нулевым (не инициирован), но после журнала 4 (было загружено второе представление), в журнале 5 txtScene1 НЕ был нулевым и был инициирован. Это предполагает, что второй вид был загружен во время выполнения segue. Итак, я предполагаю, что во время перехода segue последовательность инициализации объектов контроллера второго вида будет: контроллер второго представления -> свойство NSString (и другие подобные свойства, такие как NSInteger и т. Д.) -> второе представление -> свойство UITextfield ( другие свойства подпредставления).
Итак, я изменил свои коды в первом файле .m контроллера контроллера, как показано ниже:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
Scene2Controller *scene2ViewController = [segue destinationViewController];
[txtScene2 resignFirstResponder];
if ([scene2ViewController view]) {
if ([txtScene2.text isEqualToString:@""]) {
scene2ViewController.txtScene1.text = @"No Value";
} else {
scene2ViewController.txtScene1.text = txtScene2.text;
}
}
}
Затем этот код работает нормально, и значение передается непосредственно в свойство UITextfield во втором представлении.
Надеюсь, что приведенное выше объяснение понятно и полезно для вас.