Respuestas:
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 compilador o el tiempo de ejecución, con una grave penalización de velocidad, pero por razones obvias esto no se hace).
Tomado de Fuente .
Puede simular el acceso protegido y privado a los métodos haciendo lo siguiente:
Estas protecciones no se aplican, como señaló Sachin, en tiempo de ejecución (como en Java, por ejemplo).
UIGestureRecognizerSubclass.h
Esto es lo que hice para que los métodos protegidos fueran visibles para mis subclases, sin requerir que implementaran los métodos en sí. Esto significó que no recibí advertencias del compilador en mi subclase acerca de tener una implementación incompleta.
SuperClassProtectedMethods.h (archivo de protocolo):
@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end
@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end
SuperClass.m: (el compilador ahora te obligará a agregar métodos protegidos)
#import "SuperClassProtectedMethods.h"
@implementation SuperClass
- (void) protectedMethod:(NSObject *)foo {}
@end
Subclase.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
hacerlo.
[(id)obj hiddenMethod]
. Decir con precisión, el método protegido no es compatible con Objective-C.
Acabo de descubrir esto y me funciona. Para mejorar la respuesta de Adam, en su superclase haga una implementación del método protegido en el archivo .m pero no lo declare en el archivo .h. En su subclase, cree una nueva categoría en su archivo .m con la declaración del método protegido de la superclase y puede usar el método protegido de la superclase en su subclase. En última instancia, esto no evitará que el autor de la llamada del método supuestamente protegido sea forzado 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
protectedMethod
Otra forma de usar variables @protegidas.
@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 definir el método como un método privado de la clase principal y puede utilizarlo [super performSelector:@selector(privateMethod)];
en la clase secundaria.
Puede especie de 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 completamente un método, independientemente del tipo de instancia de llamada.
La mejor manera de hacerlo es probablemente la categoría de continuación de clase según la respuesta de @Brian Westphal, pero tendrá que redefinir el método en esta categoría para cada instancia de subclases.
Una opción es usar la extensión de clase para ocultar métodos.
En .h
:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
En .m
:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface
declaración en el archivo .m. Puede simplemente declarar una función y usarla y la tratará como privada.
Por lo general, nombro el método protegido con prefijo interno:
-(void) internalMethod;