Métodos protegidos em Objective-C

Qual é o equivalente a methods protegidos em Objective-C? Eu quero definir methods que somente as classs derivadas podem chamar / implementar.

Você não pode declarar um método protegido ou privado. A natureza dinâmica do Objective-C torna impossível implementar controles de access para methods. (Você pode fazer isso modificando fortemente o compilador ou o tempo de execução, a uma penalidade de velocidade severa, mas, por razões óbvias, isso não é feito.)

Extraído da fonte .

Você pode simular o access protegido e privado aos methods, fazendo o seguinte:

  • Declare seus methods privados em uma extensão de class (ou seja, uma categoria sem nome declarada perto do topo do arquivo ‘.m da class)
  • Declare seus methods protegidos em um header de subclass – a Apple usa esse padrão com relação ao UIGestureRecognizer (consulte a documentação e referência a UIGestureRecognizerSubclass.h)

Essas proteções não são, como observou Sachin, aplicadas em tempo de execução (como em Java, por exemplo).

Aqui está o que eu fiz para obter methods protegidos visíveis para minhas subclasss, sem exigir que eles implementassem os methods. Isso significa que eu não recebi avisos de compilador na minha subclass sobre ter uma implementação incompleta.

SuperClassProtectedMethods.h (arquivo de protocolo):

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

SuperClass.m: (o compilador agora irá forçar você a adicionar methods 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 classs importing .h files will be able to see the protected methods. 

Acabei de descobrir isso e funciona para mim. Para melhorar a resposta de Adam, em sua superclass, faça uma implementação do método protegido no arquivo .m, mas não o declare no arquivo .h. Em sua subclass crie uma nova categoria em seu arquivo .m com a declaração do método protegido da superclass e você pode usar o método protegido da superclass em sua subclass. Isso não impedirá que o responsável pela chamada 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 

Você pode definir o método como um método privado da class pai e pode usar [super performSelector:@selector(privateMethod)]; na class filho.

Outra maneira de usar 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 

Você pode 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 subclasss of the super instance though."); } @end 

Os methods não estão ocultos se você importar a categoria em outra class, mas simplesmente não o faz. Devido à natureza dinâmica do Objective-C, é impossível ocultar completamente um método, independentemente do tipo de instância do chamador.

O melhor caminho a percorrer é provavelmente a categoria de continuação de class, como foi respondida por @Brian Westphal, mas você terá que redefinir o método nesta categoria para cada instância subclass.

Uma opção é usar a extensão de class para ocultar methods.

Em .h :

 @interface SomeAppDelegate : UIResponder  @property (strong, nonatomic) UIWindow *window; @end 

Em .m :

 @interface SomeAppDelegate() - (void)localMethod; @end @implementation SomeAppDelegate - (void)localMethod { } @end