112 votes

Méthodes protégées en Objective-C

Quel est l'équivalent des méthodes protégées en Objective-C ? Je veux définir des méthodes que seules les classes dérivées peuvent appeler/implémenter.

156voto

Brian Westphal Points 1251

Vous pouvez simuler l'accès protégé et privé aux méthodes en procédant comme suit :

  • Déclarez vos méthodes privées dans une extension de classe (c'est-à-dire une catégorie sans nom déclarée en haut du fichier .m de la classe).
  • Déclarez vos méthodes protégées dans un en-tête de sous-classe - Apple utilise ce modèle pour UIGestureRecognizer (voir la documentation et la référence à UIGestureRecognizerSubclass.h).

Comme l'a fait remarquer Sachin, ces protections ne sont pas appliquées au moment de l'exécution (comme c'est le cas en Java, par exemple).

2 votes

À propos de la solution de type UIGestureRecognizer : Le problème est que si un code importe la sous-classe, il importera également l'en-tête de la sous-classe et aura donc accès aux méthodes "protégées". Existe-t-il un moyen de contourner ce problème ?

5 votes

Bonjour yonix, l'importation de l'en-tête de la sous-classe se fait dans le fichier .m et non dans le fichier .h, donc l'importation de la sous-classe n'importerait pas ces méthodes protégées.

0 votes

Cool Suggestion Brian, merci beaucoup ! !! Pour le posteur original, pour les propriétés déclarées, assurez-vous d'utiliser @dynamic dans l'implémentation de l'extension de classe de la sous-classe (catégorie non nommée), de sorte qu'au moment de l'exécution, l'implémentation de la classe parente soit utilisée.

47voto

Sachin Shanbhag Points 20979

Vous ne pouvez ni déclarer une méthode protégée ou privé. La nature dynamique d'Objective-C rend impossible l'implémentation de contrôles d'accès pour les méthodes. (Vous pourriez le faire en modifiant fortement modifier le compilateur ou le runtime, au prix d'une sévère pénalité de vitesse, mais pour des raisons évidentes, cela ne se fait pas).

Tiré de Source : .

0 votes

Bien que techniquement vous ne puissiez pas, vous pouvez émuler des variables privées.

0 votes

Lee - si vous déclarez un pointeur de fonction dans @protected et assignez une fonction dans la méthode init, cela fonctionnera-t-il ?

14voto

Michael Kernahan Points 1125

Voici ce que j'ai fait pour que les méthodes protégées soient visibles par mes sous-classes, sans qu'elles aient à les implémenter elles-mêmes. Ainsi, je n'ai pas reçu d'avertissements du compilateur dans ma sous-classe concernant une implémentation incomplète.

SuperClassProtectedMethods.h (fichier de protocole) :

@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end

@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end

SuperClass.m : (le compilateur vous forcera maintenant à ajouter des méthodes protégées)

#import "SuperClassProtectedMethods.h"
@implementation SuperClass
- (void) protectedMethod:(NSObject *)foo {}
@end

SubClass.m :

#import "SuperClassProtectedMethods.h"
// Subclass can now call the protected methods, but no external classes importing .h files will be able to see the protected methods.

2 votes

La signification de protégé c'est que c'est pas en mesure pour être appelé en externe. Vous pouvez toujours appeler toutes les méthodes définies dans la classe, qu'elles soient visibles de l'extérieur ou non.

0 votes

Oui, je comprends. Cette méthode fonctionne pour le cerveau humain, pas pour le code compilé. Mais Objective-C ne permet pas cela (ne pas pouvoir faire d'appel externe). Vous pouvez toujours performSelector sur elle.

1 votes

Vous pouvez également faire [(id)obj hiddenMethod] . En clair, la méthode protégée n'est pas supportée en Objective-C.

10voto

redwud Points 275

Pour améliorer la réponse d'Adam, dans votre superclasse, faites une implémentation de la méthode protégée dans le fichier .m mais ne la déclarez pas dans le fichier .h. Dans votre sous-classe, faites une implémentation de la méthode protégée dans le fichier .m mais ne la déclarez pas dans le fichier .h. Dans votre sous-classe, créez une nouvelle catégorie dans votre fichier .m avec la déclaration de la méthode protégée de la superclasse et vous pouvez utiliser la méthode protégée de la superclasse dans votre sous-classe. Cela n'empêchera pas en fin de compte l'appelant de la méthode supposée protégée s'il est forcé au moment de l'exécution.

/////// SuperClass.h
@interface SuperClass

@end

/////// SuperClass.m
@implementation SuperClass
- (void) protectedMethod
{}
@end

/////// SubClass.h
@interface SubClass : SuperClass
@end

/////// SubClass.m
@interface SubClass (Protected)
- (void) protectedMethod ;
@end

@implementation SubClass
- (void) callerOfProtectedMethod
{
  [self protectedMethod] ; // this will not generate warning
} 
@end

2 votes

Dans ce cas, le compilateur affiche toujours un avertissement concernant une méthode non implémentée. protectedMethod

0 votes

C'est une bonne solution, mais au lieu de créer une catégorie (Protégé), vous pouvez créer une extension.

0 votes

@skywinder Peut-être que c'était le cas dans une version antérieure, mais les versions actuelles de Xcode n'ont aucun problème avec cette solution.

1voto

chinthakad Points 301

Vous pouvez définir la méthode comme une méthode privée de la classe parente et pouvez utiliser [super performSelector:@selector(privateMethod)]; dans la classe enfant.

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