2010-11-24 18 views

Respuesta

15

Técnicamente, no. Las propiedades son métodos realmente justos, y todos los métodos son públicos. La forma en que "protegemos" los métodos en Objective-C es no dejar que otras personas se enteren de ellos.

Prácticamente, sí. Puede definir las propiedades en una extensión de clase, y todavía @synthesize en su bloque de implementación principal.

+1

Para estar "protegido", la interfaz de extensión de clase necesitaría estar en un archivo de encabezado separado para ser incluida en la clase y sus subclases. – JeremyP

+0

Hasta donde puedo decir, las propiedades declaradas en la extensión de la interfaz de las clases base no están disponibles para las subclases, tienen un ámbito privado, no están protegidas. Consulte esta discusión SO: http://stackoverflow.com/questions/5588799/objective-c-how-do-you-access-parent-properties-from-subclasses – memmons

+0

@Harkonian si declara el selector usted mismo, siempre puede llamar eso. No existe tal cosa como "proteger" un método que no sea simplemente ocultar su declaración. Objective-C no tiene el concepto de métodos privados o protegidos. Solo ivars protegidos o privados. –

0

Puede usar dicha sintaxis en la implementación de la subclase.

@interface SuperClass (Internal) 

@property (retain, nonatomic) NSString *protectedString; 

@end 
+1

¿Puede agregar una breve explicación de cómo funciona esta solución? – HairOfTheDog

9

Esto es posible mediante el uso de una extensión de clase (no de categoría) que incluye en los archivos de implementación tanto de la clase base y subclases.

Una extensión de clase se define similar a una categoría, pero sin el nombre de la categoría:

@interface MyClass() 

En una extensión de clase, se puede declarar propiedades, que será capaz de sintetizar las Ivars de respaldo (XCode> 4.4 la síntesis automática de los ivars también funciona aquí).

En la clase de extensión, puede anular/refinar propiedades (cambiar solo para leer, etc.) y agregar propiedades y métodos que serán "visibles" para los archivos de implementación (pero tenga en cuenta que las propiedades y métodos no son realmente privado y aún puede ser llamado por el selector).

Otros han propuesto el uso de un archivo de cabecera MyClass_protected.h separado para esto, pero esto también puede hacerse en el archivo de cabecera principal usando #ifdef así:

Ejemplo:

BaseClass.h

@interface BaseClass : NSObject 

// foo is readonly for consumers of the class 
@property (nonatomic, readonly) NSString *foo; 

@end 


#ifdef BaseClass_protected 

// this is the class extension, where you define 
// the "protected" properties and methods of the class 

@interface BaseClass() 

// foo is now readwrite 
@property (nonatomic, readwrite) NSString *foo; 

// bar is visible to implementation of subclasses 
@property (nonatomic, readwrite) int bar; 

-(void)baz; 

@end 

#endif 

BaseClass.m

// this will import BaseClass.h 
// with BaseClass_protected defined, 
// so it will also get the protected class extension 

#define BaseClass_protected 
#import "BaseClass.h" 

@implementation BaseClass 

-(void)baz { 
    self.foo = @"test"; 
    self.bar = 123; 
} 

@end 

ChildClass.h

// this will import BaseClass.h without the class extension 

#import "BaseClass.h" 

@interface ChildClass : BaseClass 

-(void)test; 

@end 

ChildClass.m

// this will implicitly import BaseClass.h from ChildClass.h, 
// with BaseClass_protected defined, 
// so it will also get the protected class extension 

#define BaseClass_protected 
#import "ChildClass.h" 

@implementation ChildClass 

-(void)test { 
    self.foo = @"test"; 
    self.bar = 123; 

    [self baz]; 
} 

@end 

Cuando se llama a #import, que básicamente copia-pega el archivo .h a donde está importando él. Si tiene un #ifdef, solo incluirá el código dentro si se establece el #define con ese nombre.

En su archivo .h, no establece la definición para que las clases que importan este .h no vean la extensión de clase protegida. En la clase base y el archivo .m de subclase, usa #define antes de usar #import para que el compilador incluya la extensión de clase protegida.

Cuestiones relacionadas