Métodos protegidos en Objective-C

¿Cuál es el equivalente a los métodos protegidos en Objective-C? Quiero definir métodos que solo las clases derivadas pueden llamar / implementar.

No puede declarar un método protegido o privado. La naturaleza dinámica de Objective-C hace que sea imposible implementar controles de acceso para los métodos. (Puede hacerlo modificando en gran medida el comstackdor o el tiempo de ejecución, a una penalización de velocidad severa, pero por razones obvias esto no se hace).

Tomado de la Fuente .

Puede simular el acceso privado y protegido a los métodos haciendo lo siguiente:

  • Declare sus métodos privados en una extensión de clase (es decir, una categoría sin nombre declarada cerca de la parte superior del archivo ‘.m de la clase)
  • Declare sus métodos protegidos en un encabezado de Subclase: Apple usa este patrón con respecto a UIGestureRecognizer (consulte la documentación y la referencia a UIGestureRecognizerSubclass.h)

Estas protecciones no son, como señaló Sachin, implementadas en el tiempo de ejecución (como lo son en Java, por ejemplo).

Esto es lo que hice para que los métodos protegidos sean visibles para mis subclases, sin necesidad de que implementen los métodos ellos mismos. Esto significaba que no recibí las advertencias del comstackdor en mi subclase sobre tener una implementación incompleta.

SuperClassProtectedMethods.h (archivo de protocolo):

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

SuperClass.m: (el comstackdor ahora te obligará a agregar 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. 

Acabo de descubrir esto y me funciona. Para mejorar la respuesta de Adam, en su superclase realice una implementación del método protegido en un archivo .m pero no lo declare en el archivo .h. En su subclase haga una nueva categoría en su archivo .m con la statement del método protegido de la superclase y puede usar el método protegido de la superclase en su subclase. Esto no evitará en última instancia que la persona que llama del método supuestamente protegido sea forzada en tiempo de ejecución.

 /////// 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 

Puede definir el método como un método privado de la clase principal y puede usar [super performSelector:@selector(privateMethod)]; en la clase de niños.

Otra forma de usar @protected variables.

 @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 

Puede hacer esto con una categoría.

 @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 

Los métodos no están ocultos si importa la categoría en otra clase, pero simplemente no lo hace. Debido a la naturaleza dinámica de Objective-C, en realidad es imposible ocultar por completo un método independientemente del tipo de instancia de llamada.

La mejor forma de proceder es probablemente la categoría de continuación de clase respondida por @Brian Westphal, pero deberá redefinir el método en esta categoría para cada instancia subclasificada.

Una opción es usar la extensión de clase para ocultar métodos.

En .h :

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

En .m :

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