Question

D'accord, j'ai le sentiment que vous soyez guys'll en mesure de signaler rapidement pourquoi je suis si confus à ce sujet, mais j'ai une question de savoir pourquoi ce qui suit ne donne pas lieu à une erreur du compilateur ou un avertissement:

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 embarrasse 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: retournera un NSNumber * dans ce cas particulier.

Pourquoi ne pas ce résultat dans un avertissement du compilateur le long des lignes de « id peut ne pas répondre à« -integerValue »?

Était-ce utile?

La solution

J'espère que je me trompe pas: En effet, id est « spéciale ». Les objets du type de id peut être envoyé un message que vous voulez, il n'y a pas de vérification fait par le compilateur et tout sera vérifiée dans l'exécution. Ou, en d'autres termes, le type de id est la partie de l'objectif-C, alors que tous les autres types « typage dynamique » (comme NSObject) sont la partie « typage statique ».

De cette façon, vous pouvez choisir où vous souhaitez 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 NSStrings, parce que vous obtenez la commodité de la compilation vérification de type statique, et seule station à typage dynamique où le statique obtiendrait de la manière, comme dans la situation valueForKey.

Autres conseils

Le temps est passé et nous avons une meilleure inférence de type grâce à la __auto_type disponible depuis Xcode 8. Alors maintenant, vous pouvez le faire

#define let __auto_type const
#define var __auto_type

let a = @[@"pew pew"];
var b = 2;
b = a; //compiler warning "Incompatible pointer to integer conversion assigning to 'int' from 'NSArray *__strong const'"

et beaucoup plus

En fait, je l'ai aimé ce si bien que je fait cela comme un pod pour plus de commodité.

pod 'SwiftyObjC'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top