Y a-t-il un moyen de découvrir à l'exécution quelles sous-classes existent d'une classe donnée? P>
edit: strong> des réponses jusqu'à présent, je pense que je dois clarifier un peu plus ce que j'essaie de faire. Je suis conscient que ce n'est pas une pratique courante dans le cacao et que cela peut venir avec des mises en garde. P>
J'écris un analyseur à l'aide du modèle de création dynamique. (Voir le livre Cocoa Design Motifs par Buck et Yacktman, chapitre 5.) Fondamentalement, l'instance d'analyse traite une pile et instancie des objets qui savent effectuer certains calculs. P>
Si je peux obtenir toutes les sous-classes de la classe code> myCommand code>, je peux, par exemple, fournir à l'utilisateur une liste de commandes disponibles. En outre, dans l'exemple du chapitre 5, l'analyseur a un dictionnaire de substitution afin que les opérateurs tels que +, -, * et / peuvent être utilisés. (Ils sont mappés sur MyAddCommand CODE>, etc., etc., etc.) Cela semblait que cette information appartenait à la sous-classe
MyCommand code>, pas l'instance d'analyse, car elle défait un peu l'idée de la création dynamique. p>
5 Réponses :
pas directement, non. Vous pouvez toutefois obtenir une liste de toutes classes enregistrées auprès de l'exécution et interroger ces classes pour leur directe em> superclasse. N'oubliez pas que cela ne vous permet pas de trouver tous les ancêtres pour la classe dans l'arbre d'héritage, juste la superclasse immédiate. P>
Vous pouvez utiliser Je devrais mentionner aussi que vous pourrait em> penser à la conception de votre application de manière incorrecte si vous pensez qu'il est nécessaire de faire ce genre de découverte. Très probablement, il existe un autre moyen plus conventionnel de faire ce que vous essayez d'accomplir que cela n'implique pas d'intrigité sur l'exécution de l'objectif-C. P> objc_getclasslist () code>
pour obtenir la liste des objets code> Classe code> enregistré au moment de l'exécution. Ensuite, vous pouvez faire une boucle sur ce tableau et appeler [nsobject Superclass] code> sur ces code> objets code> pour obtenir leur superclasse '
class code> objet. Si, pour une raison quelconque, vos classes n'utilisent pas
NsObject code> comme classe racine, vous pouvez utiliser
class_getsuperclass () code>
à la place. P>
Je le dirais plus fortement; Si vous pensez que vous devez le faire dans le code de production, vous le faites très probablement mal. L'introspection d'héritage à la baisse est extrêmement rare et c'est la raison pour laquelle le runtime ne le supporte pas directement. Qu'essayez-vous de faire?
@bbum j'ai ajouté une description de ce que j'essaie de faire. Pensez-vous toujours que je le fais très très mal? J'ai du mal à penser à une autre façon de le faire sans rechercher des sous-classes.
Marc et BBum l'ont frappé sur l'argent. Ce n'est généralement pas une bonne idée. P>
Cependant, nous avons du code sur notre wiki Cocoahads qui fait cela: http: // cocoahads.byeu.edu/wiki/getting-all-Subclasses p>
Une autre mise en garde; Lorsque vous faites ce genre de chose, vous finirez par causer des cours + initialisés dans une commande qu'ils n'ont peut-être jamais été initialisées auparavant. Cela ne devrait pas causer de problèmes, mais cela est parfois dû à des dépendances dans les classes système susceptibles de changer à travers les versions ...
La description du code liée indique spécifiquement que cette approche n'appelle pas + initialiser code>, et bien que je ne l'ai pas encore essayé, semble juste.
Plutôt que d'essayer d'enregistrer automatiquement toutes les sous-classes de Premièrement, fournissez API pour enregistrer une classe, quelque chose comme Ensuite, créez un code dans MyCommand qui signifie que les sous-classes s'inscrivent automatiquement. Quelque chose comme: p> myCommand code>, pourquoi pas diviser le problème dans deux?
+ [myCommand registreClass:] code>. p>
Cela ressemble à la bonne façon d'aller en effet. Surtout que la documentation mentionne que la méthode de la chargement + CODE> d'une classe est appelée après toutes ses méthodes
+ Charger CODE> CODE> DE SURCLACKES. Merci beaucoup aux autres personnes fournissant des réponses aussi, leurs réponses étaient trop grandes.
Les sous-classes de MyCommand n'appelleront pas + charger sur leur superclasse. + La charge est uniquement appelée dans des classes qui l'appliquent.
Surpris, il fallait si longtemps que quelqu'un me corrige! Je suis généralement en accord avec les réponses ici que l'enregistrement automatique est une mauvaise idée et doit être traitée un peu plus manuellement.
Il y a du code dans mon projet de navigateur d'exécution ici < / a> qui comprend un -subclassnamesForClass: méthode. Voir le runtimereporter. [Hm] code> fichiers. P>
Merci, c'est un outil intéressant à ajouter à ma ceinture. Bien que j'irai avec l'approche de Mike pour ce cas particulier.
J'ai remarqué que le lien posté par @nsresponder est cassé. Pour ceux qui recherchent un moyen de boucler à travers une hiérarchie de classe, j'ai écrit un Logger Hiérarchie de classe < / a> qui utilise une approche similaire. Cela pourrait être utile si vous avez besoin de plus de perspectives sur la façon d'itérer la hiérarchie de la sous-classe. J'espère que ça vous aide!