7 votes

Boucles for - Le type d'objet n'est pas pris en compte ?

J'aime parfois organiser les éléments de l'IB en NSArray est principalement destiné à m'aider à organiser mes éléments. Le plus souvent, différentes classes d'objets se retrouvent dans le même tableau. Bien que ce est un moyen pratique d'organisation, je n'arrive pas à comprendre pourquoi si j'ai un tableau comme celui-ci :

NSArray *array = [NSArray arrayWithObjects:((UITextField *)textField), ((UISegmentedController *)segmentedController), nil];

Pourquoi j'obtiens des messages "Ne répond pas au sélecteur" lorsque je mets un for boucle comme celle-ci :

for (UITextField *text in array) {
    [text setText:@""];
}

En for semble recevoir des objets qui ne sont pas de la classe UITextField .

Quel est l'intérêt de déclarer la classe de l'objet si tous les objets du tableau spécifié sont passés dans la boucle ?

EDIT À titre de référence, voici comment je procède pour l'instant :

for (id *object in array) {
    if ([object isMemberOfClass:[UITextField class]]) {
        foo();
    } else if ([object isMemberOfClass:[UISegmentedController class]) {
        bar();
    }
 }

10voto

SVD Points 3600

Lorsque vous le faites

for (UITextField *text in...

les pointeurs d'objets du tableau sont castés au type UITextField* - donc si l'objet n'est pas réellement un UITextField, toutes sortes de choses bizarres peuvent se produire si vous essayez d'appeler des méthodes UITextField.

Utilisez donc plutôt le type id (pas de * nécessaire) :

for (id obj in array)

Vérifiez ensuite le type au fur et à mesure et appelez les méthodes appropriées. Vous pouvez également filtrer le tableau pour n'obtenir que les objets d'un certain type, puis ne passer que par ce type :

for (UITextField* text in [array filteredArrayUsingPredicate:...])

Edit : voici comment construire des prédicats de filtrage de classe :

Est-il possible de filtrer un NSArray par classe ?

5voto

Luke Points 3529

Quel est l'intérêt de déclarer la classe de l'objet si tous les objets du tableau spécifié sont passés dans la boucle ?

Le nom de la classe n'est là que pour indiquer au compilateur ce qu'il doit s'attendre à trouver. Cela lui permet d'essayer de comprendre quelles méthodes il doit s'attendre à ce que vous appeliez et comment vous pouvez traiter l'objet. C'est la même chose que de passer un objet de type int à une méthode qui prend float . La méthode n'ignorera pas les ints - elle suppose que vous passez le bon type. Vous donnez à cette construction un peu plus de crédit qu'elle n'en a :

for (UITextField *text in array)

Il n'a tout simplement pas cette fonctionnalité. La façon dont vous gérez la situation actuellement est correcte.

0voto

Caleb Points 72897

Êtes-vous sûr que vous n'obtenez pas d'erreur lorsque vous courir ce code ? Le message "ne répond pas au sélecteur" est une erreur d'exécution, pas une erreur de compilation. Le compilateur ne sait pas si les objets du tableau implémentent la méthode -setText: mais vous devriez certainement obtenir une erreur lorsque vous envoyez ce message à une instance de UISegmentedControl .

Il est également possible que vous ayez une classe appelée UISegmentedController qui dispose d'un -setText: méthode. Le nom de la classe qui implémente le widget de l'interface utilisateur ressemblant à un graphique à barres en plusieurs parties est le suivant UISegmentedControl . Donc, soit le code que vous montrez n'est pas un vrai code testé, soit vous avez une classe que nous ne connaissons pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X