122 votes

Pourquoi Objective-C ne prend-il pas en charge les méthodes privées?

J'ai vu un certain nombre de stratégies pour la déclaration des semi-privé méthodes en Objective-C, mais il ne semble pas être un moyen de faire vraiment une méthode privée. J'accepte que. Mais, pourquoi est-ce donc? Tous les explication que j'ai dit essentiellement: "vous ne pouvez pas le faire, mais ici, c'est une approximation."

Il y a un certain nombre de mots clés appliqués ivars (les membres) que le contrôle de leur champ d'application, par exemple, @private, @public, @protected. Pourquoi ne peut-il être fait pour les méthodes ainsi? Il semble comme quelque chose que l'exécution doit être capable de supporter. Est-il une philosophie sous-jacente que je suis absent? Est-ce un choix délibéré?

102voto

bbum Points 124887

La réponse est... eh bien... simple. La simplicité et la cohérence, en fait.

Objective-C est purement dynamique au moment de la répartition de méthode. En particulier, chaque méthode de répartition passe par exactement la même dynamique de la méthode de résolution point que toute autre méthode d'expédition. Au moment de l'exécution, chaque méthode de la mise en œuvre a exactement la même exposition et toutes les Api fournies par l'Objective-C runtime qui travaillent avec des méthodes et des sélecteurs de travailler également la même dans toutes les méthodes.

Comme beaucoup l'ont déjà répondu (à la fois ici et dans d'autres questions), au moment de la compilation des méthodes privées sont pris en charge; si une classe n'est pas déclarer une méthode dans son publiquement disponibles de l'interface, alors que la méthode pourrait tout aussi bien ne pas exister autant que de votre code. En d'autres termes, vous pouvez obtenir toutes les différentes combinaisons de visibilité souhaitée au moment de la compilation par l'organisation de votre projet de façon appropriée.

Il y a peu d'avantages à en reproduisant les mêmes fonctionnalités dans runtime. Il serait ajouter une quantité énorme de complexité et de surcharge. Et même avec tout ce qui est de la complexité, il n'est pas de prévenir tous les, mais le plus décontracté des développeurs de l'exécution de votre soi-disant "privé".

EDIT: Une des hypothèses que j'ai remarqué, c'est que les messages privés seraient avoir à passer par le moteur d'exécution entraînant potentiellement une large les frais généraux. Est-ce vrai?

Oui, il est. Il n'y a aucune raison de supposer que le réalisateur d'une classe ne voulez pas utiliser la totalité de l'Objective-C ensemble de fonctions dans la mise en œuvre, et cela signifie que la distribution dynamique qui doit arriver. Cependant, il n'y a pas de raison particulière méthodes privées ne pouvait pas être distribué par une variante particulière de l' objc_msgSend(), puisque le compilateur sait qu'ils ont été privés; c'est à dire ce qui pourrait être réalisé par l'ajout d'une seule méthode de la table à l' Class de la structure.

Il n'y aurait aucun moyen pour un privé méthode de court-circuit de cette case ou passez de l'exécution?

Il ne pouvait pas ignorer l'exécution, mais l'exécution ne serait pas forcément à faire aucune vérification de méthodes privées.

Cela dit, il n'y a aucune raison pour qu'un tiers ne pouvait pas délibérément appel objc_msgSendPrivate() sur un objet, en dehors de la mise en œuvre de cet objet, et certaines choses (KVO, par exemple) aurait à le faire. En effet, il s'agirait juste d'une convention et d'un peu meilleure dans la pratique que de préfixer les méthodes privées' sélecteurs, ou de ne pas les mentionner dans l'interface d'en-tête.

Pour ce faire, cependant, serait saper la pure nature dynamique de la langue. Il n'y aurait plus de chaque méthode de répartition passer par un identique d'expédition mécanisme. Au lieu de cela, vous devez rester dans une situation où la plupart des méthodes se comporte d'une façon et une petite poignée sont simplement différentes.

Cela s'étend au-delà de l'exécution comme il existe de nombreux mécanismes en Cacao construit sur le haut de la cohérence de la dynamisme de l'Objective-C. Par exemple, à la fois Valeur de la Clé de Codage et de la Valeur de la Clé de l'Observation devrait être très fortement modifiées à l'appui de méthodes privées, probablement par la création d'une faille exploitable ou privé méthodes seraient incompatibles.

18voto

dreamlax Points 47152

Le moteur d'exécution pourrait le soutenir, mais le coût serait énorme. Chaque sélecteur qui est envoyé devra être vérifié pour savoir s'il est privé ou public pour la classe, ou chaque classe devra gérer deux tableaux de répartition. Ce n'est pas la même pour les variables d'instance parce que ce niveau de protection est fait au moment de la compilation.

Aussi, le moteur d'exécution devra vérifier que l'expéditeur d'un message privé, c'est de la même catégorie que le récepteur. Vous pouvez également contourner les méthodes privées; si la classe utilisée instanceMethodForSelector:, il pourrait donner le retour de l' IMP de toute autre classe pour eux d'appeler la méthode privée directement.

Les méthodes privées ne pouvait pas ignorer le message d'envoi. Envisagez le scénario suivant:

  1. Une classe AllPublic a un public de méthode d'instance doSomething

  2. Une autre classe HasPrivate a privé de la méthode d'instance appelée aussi doSomething

  3. Vous créez un tableau contenant un nombre quelconque de fois des instances de AllPublic et HasPrivate

  4. Vous avez la boucle suivante:

    for (id anObject in myArray)
        [anObject doSomething];
    

    Si vous avez exécuté en boucle à partir de l'intérieur d' AllPublic, le moteur d'exécution devrait cesser de vous envoyer des doSomething sur le HasPrivate des cas, cependant, cette boucle serait utilisable que si elle était à l'intérieur de l' HasPrivate classe.

13voto

mipadi Points 135410

Les réponses postées jusqu'à présent faire un bon travail de répondre à la question d'un point de vue philosophique, donc je vais donner un point de vue plus pragmatique raison: ce serait acquise par l'évolution de la sémantique de la langue? Il est assez simple de l'effet de "cacher" des méthodes privées. Par exemple, imaginez que vous avez une classe déclarée dans un fichier d'en-tête, comme suit:

@interface MyObject : NSObject {}
- (void) doSomething;
@end

Si vous avez un besoin pour des méthodes "privées", vous pouvez aussi mettre ceci dans le fichier d'implémentation:

@interface MyObject (Private)
- (void) doSomeHelperThing;
@end

@implementation MyObject

- (void) doSomething
{
    // Do some stuff
    [self doSomeHelperThing];
    // Do some other stuff;
}

- (void) doSomeHelperThing
{
    // Do some helper stuff
}

@end

Bien sûr, ce n'est pas tout à fait la même qu'en C++/Java les méthodes privées, mais c'est effectivement assez proche, alors pourquoi modifier la sémantique de la langue, ainsi que le compilateur, de l'exécution, etc., pour ajouter une fonctionnalité qui est déjà imité de façon acceptable? Comme indiqué dans d'autres réponses, le passage de message sémantique -- et sa dépendance à l'égard de l'exécution de la réflexion, de faire de la manipulation de "privé" messages non-trivial.

7voto

Cromulent Points 2308

La solution la plus simple consiste simplement à déclarer certaines fonctions C statiques dans vos classes Objective-C. Celles-ci ont uniquement une portée de fichier conforme aux règles C pour le mot clé static et à cause de cela, elles ne peuvent être utilisées que par les méthodes de cette classe.

Pas de chichi du tout.

6voto

Huperniketes Points 696

Oui, il peut être fait sans affecter l'exécution en utilisant une technique déjà utilisée par le compilateur(s) pour la manipulation de C++: nom du modificateur.

Il n'a pas été fait parce qu'il n'a pas été établi qu'il permettrait de résoudre certaines des difficultés considérables dans le codage espace-problème que d'autres techniques (par exemple, la préfixation ou ce qui souligne) sont en mesure de contourner suffisamment. OIE, vous avez besoin de plus la douleur pour surmonter les habitudes bien ancrées.

Vous pourriez contribuer patchs pour clang ou gcc ajouter des méthodes privées à la syntaxe et généré des noms déformés qu'elle est la seule reconnue lors de la compilation (et rapidement oublié). Puis d'autres dans l'Objective-C de la communauté serait en mesure de déterminer si c'était réellement la peine ou non. Il est susceptible d'être plus rapidement de cette façon que d'essayer de convaincre les développeurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X