Respostas:
Você não pode declarar um método protegido ou privado. A natureza dinâmica do Objective-C torna impossível implementar controles de acesso para métodos. (Você poderia fazer isso modificando fortemente o compilador ou o tempo de execução, com uma grande penalidade de velocidade, mas por razões óbvias isso não é feito.)
Retirado da fonte .
Você pode simular o acesso protegido e privado a métodos fazendo o seguinte:
Essas proteções não são, como observou Sachin, aplicadas em tempo de execução (como no Java, por exemplo).
UIGestureRecognizerSubclass.h
Aqui está o que fiz para tornar os métodos protegidos visíveis para minhas subclasses, sem exigir que eles implementem os métodos. Isso significa que não recebi avisos do compilador em minha subclasse sobre uma implementação incompleta.
SuperClassProtectedMethods.h (arquivo de protocolo):
@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end
@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end
SuperClass.m: (o compilador agora o forçará a adicionar métodos protegidos)
#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.
performSelectorisso.
[(id)obj hiddenMethod]. Dizendo com precisão, o método protegido não é compatível com Objective-C.
Acabei de descobrir isso e funciona para mim. Para melhorar a resposta de Adam, em sua superclasse, faça uma implementação do método protegido no arquivo .m, mas não o declare no arquivo .h. Em sua subclasse, crie uma nova categoria em seu arquivo .m com a declaração do método protegido da superclasse e você pode usar o método protegido da superclasse em sua subclasse. Isso não impedirá que o chamador do método supostamente protegido seja forçado no tempo de execução.
/////// 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
Outra forma de usar variáveis @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
Você pode definir o método como um método privado da classe pai e pode usar [super performSelector:@selector(privateMethod)];na classe filha.
Você pode tipo de fazer isso com uma categoria.
@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
Os métodos não são ocultados se você importar a categoria em outra classe, mas você simplesmente não o faz. Devido à natureza dinâmica de Objective-C, é realmente impossível ocultar completamente um método, independentemente do tipo de instância de chamada.
O melhor caminho a seguir é provavelmente a categoria de continuação de classe, conforme respondido por @Brian Westphal, mas você terá que redefinir o método nesta categoria para cada instância de subclasse.
Uma opção é usar extensão de classe para ocultar métodos.
Em .h:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
Em .m:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interfacedeclaração no arquivo .m. Você pode simplesmente declarar uma função e usá-la e ela a tratará como privada.