7
votes

Objective-C pointeur à la classe qui implémente un protocole

J'ai trois classes qui implémentent le même protocole et ont la même classe mère qui ne met pas en œuvre le protocole. Normalement, j'aurais le protocole comme des fonctions virtuelles pures dans la classe mère, mais je n'ai pas pu trouver un moyen de l'objectif-c de faire cela.

Je veux utiliser le polymorphisme sur ces sous-classes en déclarant des fonctions virtuelles pures dans la superclasse, puis ont Les enfants mettent en œuvre ces fonctions. Cependant, le seul moyen objectif - C J'ai trouvé que chaque enfant décider explicitement de mettre en œuvre un protocole, lorsque je le fais de cette façon, la superclasse ne sait pas que les enfants mettront en œuvre ce protocole, il y a des avertissements de temps compilés. partout sur la place.

Un peu pseudo-code si cela n'avait pas de sens: xxx

le consommateur de ces classes: < PRE> XXX

La seule façon Nice que j'ai trouvée faire des fonctions virtuelles pures dans l'objectif-C est un hack en mettant [auto-newnoRecognecteur: _cmd]; dans la classe mère , mais ce n'est pas idéal car cela provoquera des erreurs d'exécution plutôt que de compiler l'heure.


1 commentaires

Il semble que la manière de l'OBJC de méthodes pure-virtuel / abstraites soit des "clusters de classe". Pourrait être quelque chose qui vaut la peine d'être enquêté pour vous.


4 Réponses :


11
votes

Les développeurs d'Objective-C utilisent couramment une vérification dynamique plutôt que sur la vérification du temps compilé dans ces situations car la langue et les cadres l'appuient si bien. Donc, par exemple, vous pouvez écrire votre méthode comme celle-ci:

- (void)someMethod
{
    // See if the object in currentView conforms to MyProtocol
    //
    if ([currentView conformsToProtocol:@protocol(MyProtocol)])
    {
        // Cast currentView to the protocol, since we checked to make
        // sure it conforms to it. This keeps the compiler happy.
        //
        [(SuperClass<MyProtocol> *) currentView protocolMethod];
    }
}


4 commentaires

Bien sûr, il est plus fiable d'utiliser répondselector: @Selector (protocolmethod) .


... et nécessaire si le protocole a des méthodes facultatives.


Je n'encouragerais pas d'utiliser des informations de type de temps d'exécution comme celle-ci - il est très peu probable que ce soit un véritable cas où vous ne connaissez pas le type de votre objet assez bien au moment de la compilation pour éviter de le faire. Les cas les plus courants où j'ai vu RTTI utilisés sont redondants avec un peu de pensée. L'exception est la mise en œuvre du code de type générique dans l'objectif-C où, malheureusement, nous sommes obligés d'utiliser un mécanisme fondamentalement moins efficace que le compilateur est capable de générer du code pour, simplement parce qu'il n'y a pas de générique de compilation dans la spécification de la langue (A problème partagé avec / hérité de c). Aussi, Remote Exec


Je pense que les programmeurs de l'objectif-C n'utilisent pas de vérification de type dynamique car "les cadres le supporte si bien", nous l'utilisons car le système de vérification du type statique n'est pas suffisamment expressif pour le renoncer.



1
votes

Personnellement, je voudrais mettre en œuvre le protocole sur la super classe, mais mettre en œuvre les méthodes telles que ceci: xxx

de cette façon si vous oubliez de remplacer une méthode dans une sous-classe concrète, elle devrait être immédiatement évident.


3 commentaires

Cela dépend si toutes les sous-classes devraient être conformes au protocole; Pas vraiment sûr de ce que Winder est en tête. Mais je ne pose certainement pas ces affirmations dans mon code de production. Je préférerais simplement fournir des méthodes vides et peut-être loger un avertissement.


En fait, j'allais suggérer une sorte du contraire: envisagez de faire des méthodes de protocole facultatives et faites le chèque d'exécution, mais à nouveau, cela dépend vraiment de l'intention.


C'est le comportement que je veux, juste avec une erreur de compilateur plutôt que d'un runtime. Cela ne ressemble pas à l'Objectif-C a un moyen de le faire.



3
votes

Alternativement, vous pouvez utiliser le suivant

if ([unknownObject conformsToProtocol:@protocol(MyProtocol)])
   [unknownObject methodInProtocol];  // will cause warning


0 commentaires

5
votes

J'ai pu obtenir le compilateur pour me prévenir correctement en faisant le Superclass * CurrentView Propriété ressemble à ceci: XXX


0 commentaires