Réponses:
Vous ne pouvez ni déclarer une méthode protégée ni privée. La nature dynamique d'Objective-C rend impossible la mise en œuvre de contrôles d'accès pour les méthodes. (Vous pouvez le faire en modifiant fortement le compilateur ou le runtime, avec une pénalité de vitesse sévère, mais pour des raisons évidentes, cela n'est pas fait.)
Tiré de la source .
Vous pouvez simuler un accès protégé et privé aux méthodes en procédant comme suit:
Ces protections ne sont pas, comme Sachin l'a noté, appliquées à l'exécution (comme elles le sont en Java, par exemple).
UIGestureRecognizerSubclass.h
Voici ce que j'ai fait pour que les méthodes protégées soient visibles par mes sous-classes, sans leur demander d'implémenter les méthodes elles-mêmes. Cela signifiait que 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 va maintenant vous forcer à 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.
performSelector
dessus.
[(id)obj hiddenMethod]
. En disant avec précision, la méthode protégée n'est pas prise en charge dans Objective-C.
Je viens de découvrir cela et cela fonctionne pour moi.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, 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 finalement pas l'appelant de la méthode supposée protégée si elle est forcée 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
protectedMethod
Une autre façon d'utiliser les variables @protected.
@interface SuperClass:NSObject{
@protected
SEL protectedMehodSelector;
}
- (void) hackIt;
@end
@implementation SuperClass
-(id)init{
self = [super init];
if(self) {
protectedMethodSelector = @selector(baseHandling);
}
return self;
}
- (void) baseHandling {
// execute your code here
}
-(void) hackIt {
[self performSelector: protectedMethodSelector];
}
@end
@interface SubClass:SuperClass
@end
@implementation SubClass
-(id)init{
self = [super init];
if(self) {
protectedMethodSelector = @selector(customHandling);
}
return self;
}
- (void) customHandling {
// execute your custom code here
}
@end
Vous pouvez définir la méthode en tant que méthode privée de la classe parent et l'utiliser [super performSelector:@selector(privateMethod)];
dans la classe enfant.
Vous pouvez en quelque sorte le faire avec une catégorie.
@interface SomeClass (Protected)
-(void)doMadProtectedThings;
@end
@implementation SomeClass (Protected)
- (void)doMadProtectedThings{
NSLog(@"As long as the .h isn't imported into a class of completely different family, these methods will never be seen. You have to import this header into the subclasses of the super instance though.");
}
@end
Les méthodes ne sont pas masquées si vous importez la catégorie dans une autre classe, mais vous ne le faites pas. En raison de la nature dynamique d'Objective-C, il est en fait impossible de masquer complètement une méthode quel que soit le type d'instance appelante.
La meilleure façon de procéder est probablement la catégorie de continuation de classe à laquelle a répondu @Brian Westphal, mais vous devrez redéfinir la méthode dans cette catégorie pour chaque instance sous-classée.
Une option consiste à utiliser l' extension de classe pour masquer les méthodes.
Dans .h
:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
Dans .m
:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface
déclaration dans le fichier .m. Vous pouvez simplement déclarer une fonction et l'utiliser et elle la traitera comme privée.