Escribí un artículo similar a ActionScript hace mucho tiempo: ActionScript 3.0: public, protected, privado e interno . Al releerlo, me di cuenta de dos cosas: la primera fue la extrema similitud con Objective-C, aunque este último no incluye internal . La segunda es que yo estaba, en ese momento, muy conciso ... Yo no repetir ese error ahora.
Una declaración de la clase
En Objective-C, al igual que en otros lenguajes orientados a objetos, puede especificar la visibilidad de una o más variables declaradas en la interfaz. Objective-C tiene 3 palabras clave para determinar la visibilidad de una variable:
1 2 3 | @ Pública @ Protegida @ Privado |
Su uso no es obligatorio. Todas las variables declaradas en la interfaz de una clase son, por defecto, @protected a menos que se indique lo contrario.
Si escribimos una clase que se utilizará para la subclase, que es una clase que herede sus características de otro, las tres palabras clave que aparecen arriba, son fundamentales, o por lo menos sería una buena idea utilizar de manera adecuada.
Vemos un claro ejemplo de las diferencias.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | NSObject @ Interface ClassA: NSObject { @ Pública int publicVar; @ Protected / / Protegido es el valor predeterminado int protectedVar; @ Privado int privatevar; } @ End @ Implementación ClassA id ) init { - (Id) init { self = [ super init ] ) { if (self = [super init]) { ; publicVar = 2; ; protectedVar = 10; ; privatevar = 16; } volver yo; } @ End |
En el ejemplo anterior, el método init ve y puede establecer las tres variables. : Pero veamos lo que sucede cuando creamos una clase ClassB hereda de ClassA :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | / / ClassB es una subclase de ClassA ClassA { @ Interface ClassB: ClassA { @ Privado int privateVarClassB; } @ End @ Implementación ClassB id ) init { - (Id) init { self = [ super init ] ) { if (self = [super init]) { / / PublicVar puede acceder por cualquier persona ; publicVar = 32; / / Incluso protectedVar es accesible desde ClassB, porque las variables / / @ Protegidas son accesibles por las subclases ; protectedVar = 64; / / Privatevar generará un error de compilación, porque las variables / / @ Privadas no son accesibles a las subclases ; // COMPILER ERROR HERE privatevar = 128, / / Error del compilador AQUÍ / / PrivateVarClassB, obviamente, será accesible aquí, como / / Aunque se define como "privada", que no es para ClassB, que ha declarado ; privateVarClassB = 512; } volver yo; } @ End |
Como ejemplo ilustrativo final, vamos a ver qué pasa con la instancia de clase:
Nota: Ahora intenta acceder al Ivar (variables internas) con la instancia de la clase
ClassBy no ereditandola. Esta es una diferencia importante y muy importante en comparación con los ejemplos anteriores, ya que demuestra la vulnerabilidad del código si no utiliza las palabras claves correctas para la visibilidad
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | / / Definir cualquier otra clase que utiliza su / / Instancia interna de ClassB definido anteriormente NSObject { @ Interface ClassXYZ: NSObject { ClassB * ClassB; } @ End @ Implementación ClassXYZ id ) init { - (Id) init { self = [ super init ] ) { if (self = [super init]) { ClassB alloc ] init ] ; ClassB = [[ClassB alloc] init]; / / Como el anterior, publicVar fue declarado "público" y luego / / Accesible como Ivar - cuenta el indicador de "puntero" -> 1024 ; ClassB -> publicVar = 1,024; / / En su lugar, tratar de acceder a la Ivar llamado "protegido" o / / "Privado", el compilador emitirá un ERROR 2048 ; ClassB -> protectedVar = 2,048; 4096 ; ClassB -> privatevar = 4,096; 8192 ; ClassB -> privateVarClassB = 8,192; } volver yo; } @ End |
perché dichiarata all'interno di @public . El método init puede cambiar el Ivar publicVar ya declarado en @public . Esto, en sí mismo, no es un error, pero es un procedimiento que debe ser evaluado cuidadosamente porque expone el código para posibles infiltraciones externas no échale un vistazo! Las propiedades de una clase, de hecho, tienen la doble ventaja de proteger la Ivar interno y compruebe la configuración de un Ivar exterior.
Bloqueos de seguridad en el código de
He aquí algunas reglas para asegurarse de que no contaminen las variables de un objeto de forma involuntaria. Tipo de declaración:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | NSObject @ Interface ClassA: NSObject { @ Privado privateVarA int / uso / Interna _propertyA int / propiedad / Ivar } propertyA; @ Property int propertyA; @ End @ Implementación ClassA _propertyA; @ Sintetizar propertyA = _propertyA; id ) init { - (Id) init { super init ] ; self = [super init]; self ) { if (auto) { ; // Uso interno privateVarA = uso 16384 / / Interna ; // Valore di default della proprietà propertyA _propertyA valor = 64 / / por defecto de la propiedad propertyA } } @ End |
Nadie de afuera puede acceder a la Ivar declaró. . La única Ivar es accesible _propertyA , estableciendo la propiedad propertyA . si riflette automaticamente sulla ivar _propertyA . Después de haber utilizado @synthesize propertyA = _propertyA; tenemos un medio de protección, ya que cualquier valor de atributo de la propiedad propertyA se refleja automáticamente en la Ivar _propertyA . Sin embargo, usted puede agregar fácilmente una armadura adicional mediante la inserción de la aplicación:
1 2 3 4 5 6 7 | / / Sobrescribir el colocador predeterminado creado por @ sintetizan void ) setPropertyA : ( int ) aValue { - (Void) setPropertyA: (int) aValue { / / Establecer el Ivar y la propiedad sólo bajo ciertas condiciones aValue > = 0 && aValue < = 512 ) { if (aValue> = 0 && aValue <= 512) { _propertyA = aValue; } } |
) avrà sempre valori compresi tra 0 e 512. De esta forma nos hemos asegurado de que la variable interna Ivar _propertyA (y por lo tanto automáticamente la propiedad propertyA ) siempre tendrá valores entre 0 y 512.
Por lo tanto, siempre da buen uso Ivar (a menudo denotado por un guión bajo delante) en la visibilidad @private . Cuando sea necesario, a continuación, escriba sus métodos setter y getter, evitando el uso de @synthesize .











No hay comentarios para este post
Deja un comentario