En Objective-C, en fonction d'un id, comment puis-je savoir quel type d'objet il s'points?
Objective-C newbie question. Compte tenu de la suite (fictif) code:
id mysteryObject = [anotherObject mysteriousMethod];
Comment puis-je déterminer au moment de l'exécution de la classe mysteryObject
est?
Vous devez vous connecter pour publier un commentaire.
vous obtiendrez la classe de l'objet. Cependant, en général, vous voulez faire quelque chose OOPy comme la vérification de la conformité à certaines protocole ou de l'interface.
Vous pouvez utiliser
isKindOfClass
ouisMemberOfClass
Par exemple:
if ([foo isMemberOfClass:[NSBar class]])
isKindOfClass
signifie que l'objet hérite de la classe,isMemberOfClass
signifie exactement de la même classeisKindOfClass
signifie exactement de la même classe tout en signifiant également l'objet hérite de la classeDans un typées dynamiquement langue comme l'Objective-C (ou Python ou Ruby), vous ne sont souvent pas voulez de savoir quel type d'objet il s'agit. Il est souvent plus productif de penser que l'objet répond au message que vous souhaitez envoyer; si elle le fait, vous ne devriez pas vous soucier de ce que la classe qu'il instancie et si ça ne marche pas, vous devez traiter le cas, quelle que soit l'instance du type. Ceci est connu comme "duck typing"...si c'charlatans comme un canard, c'est un canard.
Vous pouvez tester si un objet répond à un message particulier (connu comme un sélecteur en Objective-C) comme ceci:
Même mieux que de tester pour chaque sélecteurs est de définir un
@protocol
qui décrit l'API que vous souhaitez utiliser pour vos classes:Vous pouvez tester si une instance met en œuvre la
MyProtocol
protocole comme ceci:Cette façon de faire est souvent mal à l'aise pour les gens venant de langages statiquement typés comme le Java ou le C++. Vous perdez le compilateur de vérifier types pour vous. Typage dynamique qui fait un grand nombre de choses plus facile, cependant, y compris les tests puisque vous pouvez facilement remplacer une instance avec une faux à la durée du test. Ainsi, la dynamique de la langue de l'approche est de tester plus et de se soucier de types moins. Vous avez une bonne couverture de tests unitaires, n'est-ce pas?
Si vraiment vous devez déterminer la classe d'une instance au moment de l'exécution (et vous avez vraiment n'avez pas besoin probablement de), vous pouvez utiliser
-[NSObject isKindOfClass:]
pour tester si une instance est une instance d'une classe ou d'un quelconque de ses sous-classes ou-[NSObject isMemberOfClass:]
pour tester si une instance est une instance d'une classe particulière. Vous pouvez inspecter laClass
objet directement comme le retour de-[NSObject class]
et vous pouvez obtenir le nom de la chaîne de l'instance de la classe avecNSStringFromClass([mysteryInstance class])
.J'ai trouvé que j'avais de jeter en arrière pour l'id d'lorsqu'il est utilisé avec une méthode définie dans une @protocole.
Par exemple, de soi.les auditeurs est un tableau d'id
Si je fais cela ....
J'obtiens une erreur "ne connaît Aucune méthode d'instance pour sélecteur de "classe"". Pourtant, quand je lance l'id à partir de l'id de l'id ça marche ... Pourquoi je ne comprends pas.
Voici la boucle complète ...
NSObject
protocole (oui, c'est différent, bien que liés, à la classe). Voir ici. Cela permettra de résoudre vos problèmes avec le-class
méthode. 2. Je devine que vous êtes probablement désireux de savoir si la classe exemple répond à un sélecteur, par exemple[myObject respondsToSelector:sel]
, plutôt qu'à la classe elle-même[[myObject class] responds...]
.