Las directivas @ pública, @protected y @private son no comprometen de Objective-C, que son compilador pistas sobre la accesibilidad de las variables. NO LE RESTRINGE a usted de acceder a ellos.
ejemplo:
@interface Example : Object
{
@public
int x;
@private
int y;
}
...
...
id ex = [[Example alloc ] init];
ex->x = 10;
ex->y = -10;
printf(" x = %d , y = %d \n", ex->x , ex->y);
...
El compilador gcc escupe:
Main.m: 56: 1: advertencia: instance variable ‘y’ es @private; esto será un error difícil en el futuro
Main.m: 57: 1: advertencia: la variable de instancia 'y' es @private; este será un error de hardware en el futuro
una vez para cada acceso "innapropriate" a "privado" miembro y, pero compila todos modos.
Cuando se ejecuta se obtiene
x = 10 , y = -10
Así que realmente depende de usted no escribir código de acceso de esta manera, sino porque objc es un superconjunto de C, sintaxis de C funciona muy bien, y todo las clases son transparentes.
Puede configurar el compilador para tratar estas advertencias como errores y fianza, pero el objetivo-C no está configurado internamente para este tipo de rigor. El envío de métodos dinámicos debería verificar el alcance y el permiso de cada llamada (slooooowwwww ...), por lo que, más allá de una advertencia en tiempo de compilación, el sistema espera que el programador respete el alcance de los miembros de datos.
Existen varios trucos para obtener la privacidad de los miembros en el objetivo-C. Una es asegurarse de poner la interfaz y las implementaciones de su clase en archivos .h y .m separados, respectivamente, y poner los miembros de datos en el archivo de implementación (el archivo .m). Entonces los archivos que importan los encabezados no tienen acceso a los miembros de datos, solo la clase en sí. A continuación, proporcione los métodos de acceso (o no) en el encabezado. Puede implementar las funciones setter/getter en el archivo de implementación para fines de diagnóstico si lo desea y serán habilitadas, , pero el acceso directo a los miembros de los datos no se realizará.
ejemplo:
@implementation Example2 :Object
{
//nothing here
}
double hidden_d; // hey now this isn't seen by other files.
id classdata; // neither is this.
-(id) classdata { return [classdata data]; } // public accessor
-(void) method2 { ... }
@end
// this is an "informal category" with no @interface section
// these methods are not "published" in the header but are valid for the class
@implementation Example2 (private)
-(void)set_hidden_d:(double)d { hidden_d = d; }
// You can only return by reference, not value, and the runtime sees (id) outside this file.
// You must cast to (double*) and de-reference it to use it outside of this file.
-(id) hidden_d_ptr { return &hidden_d;}
@end
...
[Main.m]
...
ex2 = [[Example2 alloc] init];
double d = ex2->hidden_d; // error: 'struct Example2’ has no member named ‘hidden_d’
id data = ex2->classdata; // error: 'struct Example2’ has no member named ‘classdata’
id data = [ex2 classdata] // OK
[ex2 set_hidden_d : 6.28318 ]; // warning:'Example2' may not respond to '-set_hidden_d:'
double* dp = [ex2 hidden_d_ptr]; // (SO UGLY) warning: initialization from incompatible pointer type
// use (double*)cast -- <pointer-to-pointer conversion>
double d = (*dp); // dereference pointer (also UGLY).
...
El compilador emitirá advertencias para tales chanchullos flagrantes, pero seguirá adelante y la confianza que usted sabe lo que está haciendo, y que tiene sus razones (ver (en realidad?) ¿tú?). ¿Parece mucho trabajo? ¿Propenso a errores? ¡Yay Baby! Intente refactorizar su código primero antes de recurrir a los trucos mágicos de C y la cirugía de albóndigas como esta.
Pero ahí está. Buena suerte.
En concreto, el compilador en cuestión parece ser Clang> 2. (Existente) GCC no lo hará. –
En este contexto, 'Clang' es lo mismo que 'LLVM', ¿verdad? –
@ranReloaded - no. Hay gcc - gcc front & backend, gcc-llvm - gcc frontend, llvm backend - y clang - clang frontend, llvm backend. Solo probé el clang, Josh probó en uno de los gcc. YMMV, solo inténtalo con el compilador que estés usando y mira. – CRD