The directives @public, @protected, and @private are
not binding in objective-C, they are compiler hints about
the accessibility of the variables.
It DOES NOT RESTRICT YOU from accessing them.
例如:
@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
", ex->x , ex->y );
...
gcc 编织物:
Main.m:56:1: 警告:可变的“y”是@ private;这将是未来的一个硬错误。
Main.m:57:1: 警告:可变的“y”是@ private;这将是未来的一个硬错误。
once for each "innapropriate" access to "private" member y, but compiles it anyway.
当你出面时
x = 10 , y = -10
So it really is up to you NOT to write access code this way, but because objc is a superset of C,
C syntax works just fine, and all classes are transparent.
你可以设立汇编者,将这些警告作为错误和保释处理——但目标C并不是为了这种严格性而在内部建立。 动态方法的发送必须检查每次电话(Sloooowwwww.......)的范围和许可,因此,除了汇编时间的警告外,该系统期望方案者尊重数据成员的范围。
There are several tricks to getting privacy of members in objective-C.
One is to make sure you put the interface and implementations of your class in separate .h and .m files, respectively, and put the data members in the implementation file (the .m file).
Then the files that import the headers do not have access to the data members, only the class itself.
Then provide access methods (or not) in the header. You can implement setter/getter functions
in the implementation file for diagnostic purposes if you want and they will be callable,
but direct access to the data members will not be.
例如:
@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).
...
The compiler will issue warnings for such blatant shenanigans, but will go ahead
and trust that you know what you are doing (really?), and that you have your reasons (do you?).
Seem like a lot of work? Error Prone? Yay Baby!
Try refactoring your code first before resorting to magic C tricks and meatball surgery like this.
But there it is. Good luck.