2010-01-16 6 views
8

Bon, j'ai l'impression que vous serez capable de rapidement montrer pourquoi je suis si confus à ce sujet, mais j'ai une question pour savoir pourquoi ce qui suit ne résulte pas en un compilateur erreur ou d'avertissement:Inférence de type Objective-C

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ]; 

selectedObject est un NSObject et name se trouve être le nom d'un @property de type int.

Ce qui me déconcerte est pourquoi le compilateur est parfaitement prêt à supposer que le résultat de retour de [ self.selectedObject valueForKey:name ] est de type NSNumber * (sans typecasting il) afin d'enchaîner le message avec un appel à integerValue.

De toute évidence, KVC se termine non un type d'objet « numéro » dans NSNumber, mais il n'y a aucun moyen pour le compilateur de savoir que -valueForKey: retourne un NSNumber * dans ce cas particulier. Pourquoi cela ne résulte-t-il pas en un avertissement du compilateur suivant les lignes de "id ne peut pas répondre à '-integerValue'"?

Répondre

10

J'espère que j'ai compris: c'est parce que id est "spécial". Les objets du type id peuvent recevoir n'importe quel message, il n'y a pas de vérification effectuée par le compilateur et tout sera vérifié à l'exécution. Ou, en d'autres termes, le type id est la partie "typage dynamique" d'Objective-C, alors que tous les autres types (comme NSObject) sont la partie "typage statique". De cette façon, vous pouvez choisir où vous voulez utiliser le typage statique, et où vous voulez utiliser le typage dynamique. Il est parfaitement légal de faire quelque chose comme ceci:

id str1 = @"Hello"; 
id str2 = [str1 stringByAppendingString:@", world"]; 

Mais généralement, vous tapez les chaînes « bien » comme NSString s, parce que vous obtenez la commodité de la compilation vérification de type statique, et ne recourir à typage dynamique où le statique serait dans le chemin, comme dans la situation valueForKey.

+0

Merci! J'avais l'impression que ça avait à voir avec 'id' étant un type privilégié dans Objective-C. :) Ma tendance est de toujours TOUJOURS taper les choses à chaque fois que possible, donc je suppose que je n'ai jamais rencontré ce comportement apparemment étrange. Devinez qui rend 'id 'à la fois puissant et dangereux. Je me demande s'il est préférable de faire un typage pour donner au compilateur un peu de contexte quand il s'agit de 'id', ou s'il est parfaitement acceptable de ne pas le faire si vous êtes sûr de ce que deviendra id (comme dans mon exemple) . – LucasTizma

+0

La règle du pouce est: "Taper statiquement là où c'est possible, dactylographie dynamique si nécessaire." (Vous pouvez utiliser Google pour obtenir plus d'informations.) Dans ce cas je ne serais pas catalogué, cela rendrait l'expression plus difficile à lire. Parfois, vous devez cataloguer pour aider le compilateur à choisir la bonne méthode - voir http://stackoverflow.com/questions/1113270. – zoul

+0

Merci pour le lien. J'ai rencontré quelques petits bogues désagréables à la suite de la dénomination de la méthode qui est en conflit avec les noms de méthodes SDK existants. Je pensais que le compilateur devenait fou sur moi. :) Et oui, je suis totalement un partisan de la «dactylographie statique où possible, dactylographie dynamique lorsque nécessaire». Maintenant, si seulement Objective-C ajoutait un support pour les collections typées ... Apparemment le plus souvent, je sais ce que mes collections vont stocker. – LucasTizma

Questions connexes