Je viens de rencontrer le même problème récemment. Mais lorsque je le débogue étape par étape, je trouve une raison possible. (Je suis désolé, je suis aussi nouveau en Objective C, donc mon explication suivante peut ne pas être aussi précise et professionnelle ... Mon expérience précédente est principalement dans le développement web.)
Si vous placez un point d'arrêt juste après la ligne où vous appelez
testViewController *viewController = segue.destinationViewController;
lorsque vous compilez et lancez le projet, vous constaterez que la propriété UITextField dans destinationViewController n'est pas allouée et initialisée (la mémoire est à 0x0) au point d'arrêt. Pendant ce temps, la propriété NSString est déjà allouée et initialisée (vous pouvez donc définir sa valeur).
Je pense que probablement UITextfield est une vue enfant, donc il est seulement initialisé lorsque sa vue parente (la vue destination) est initialisée. Mais NSString est une propriété qui n'est pas associée à une vue spécifique, donc elle est allouée et initialisée avec le contrôleur de vue qui la déclare.
Lorsque j'ai fait un test plus approfondi, j'ai trouvé quelque chose de très intéressant : la deuxième vue est chargée pendant l'exécution de - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
. J'ai fait un code de test comme ci-dessous :
Dans le fichier .m du premier contrôleur de vue :
- (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 est la propriété UITextfield que j'ai déclarée dans le deuxième contrôleur de vue
//txtScene2 est la propriété UITextfield que j'ai déclarée dans le premier contrôleur de vue
//passValue est la propriété NSString que j'ai déclarée dans le deuxième contrôleur de vue
}
Dans le fichier .m du deuxième contrôleur de vue :
- (void)viewDidLoad
{
NSLog("6. txtScene1 : %; passValue : %", txtScene1,passValue);
[super viewDidLoad];
}
Remarquez que j'ai ajouté des numéros séquentiels avant les messages NSLog. J'ai constaté que la séquence finale de logs était 1,2,3,6,4,5 plutôt que 1,2,3,4,5,6. Et dans le log 3, le résultat de txtScene1 était nul (non initialisé), mais après le log 4 (la deuxième vue était chargée), dans le log 5, txtScene1 n'était PAS nul et avait été initialisé. Cela suggère que la deuxième vue était chargée pendant l'exécution du segue. Donc je suppose que pendant la transition de segue, la séquence d'initialisation des objets du contrôleur de vue de la deuxième vue serait : contrôleur de vue de la deuxième vue -> propriété NSString (et autres propriétés similaires, comme NSInteger, etc.) -> deuxième vue -> propriété UITextfield (et autres propriétés de sous-vue).
J'ai donc modifié mes codes dans le fichier .m du premier contrôleur de vue comme suit :
- (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;
}
}
}
Ce code fonctionne ensuite correctement et la valeur est passée directement à la propriété UITextfield dans la deuxième vue.
J'espère que l'explication ci-dessus est claire et utile pour vous.