9
votes

Découvrez les sous-classes d'une classe donnée à Obj-C

Y a-t-il un moyen de découvrir à l'exécution quelles sous-classes existent d'une classe donnée?

edit: 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.

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.

Si je peux obtenir toutes les sous-classes de la classe myCommand , 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 , etc., etc., etc.) Cela semblait que cette information appartenait à la sous-classe MyCommand , pas l'instance d'analyse, car elle défait un peu l'idée de la création dynamique.


0 commentaires

5 Réponses :


19
votes

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 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.

Vous pouvez utiliser objc_getclasslist () pour obtenir la liste des objets Classe enregistré au moment de l'exécution. Ensuite, vous pouvez faire une boucle sur ce tableau et appeler [nsobject Superclass] sur ces objets pour obtenir leur superclasse ' class objet. Si, pour une raison quelconque, vos classes n'utilisent pas NsObject comme classe racine, vous pouvez utiliser class_getsuperclass () à la place.

Je devrais mentionner aussi que vous pourrait 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.


2 commentaires

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.



4
votes

Marc et BBum l'ont frappé sur l'argent. Ce n'est généralement pas une bonne idée.

Cependant, nous avons du code sur notre wiki Cocoahads qui fait cela: http: // cocoahads.byeu.edu/wiki/getting-all-Subclasses


2 commentaires

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 , et bien que je ne l'ai pas encore essayé, semble juste.



13
votes

Plutôt que d'essayer d'enregistrer automatiquement toutes les sous-classes de myCommand , pourquoi pas diviser le problème dans deux?

Premièrement, fournissez API pour enregistrer une classe, quelque chose comme + [myCommand registreClass:] .

Ensuite, créez un code dans MyCommand qui signifie que les sous-classes s'inscrivent automatiquement. Quelque chose comme: xxx


3 commentaires

Cela ressemble à la bonne façon d'aller en effet. Surtout que la documentation mentionne que la méthode de la chargement + d'une classe est appelée après toutes ses méthodes + Charger 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.