关于ios:“@private”在Objective-C中意味着什么?

What does “@private” mean in Objective-C?

在目标C中,@private是什么意思?


它是一个可见性修饰符,它意味着声明为@private的实例变量只能由同一类的实例访问。子类或其他类无法访问私有成员。

例如:

1
2
3
4
5
6
7
8
9
@interface MyClass : NSObject
{
    @private
    int someVar;  // Can only be accessed by instances of MyClass

    @public
    int aPublicVar;  // Can be accessed by any object
}
@end

此外,为了澄清,方法在Objective-C中始终是公开的。有一些方法可以"隐藏"方法声明,不过有关更多信息,请参阅此问题。


正如HTW所说,它是一个可见性修改器。@private表示只能从同一类的实例中直接访问ivar(实例变量)。然而,这对你来说可能并不重要,所以让我举个例子。为了简单起见,我们将使用类的init方法作为示例。我将在线评论,指出感兴趣的项目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@interface MyFirstClass : NSObject
{
    @public
    int publicNumber;

    @protected  // Protected is the default
    char protectedLetter;

    @private
    BOOL privateBool;
}
@end

@implementation MyFirstClass
- (id)init {
    if (self = [super init]) {
        publicNumber = 3;
        protectedLetter = 'Q';
        privateBool = NO;
    }
    return self;
}
@end
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
29
30
@interface MySecondClass : MyFirstClass  // Note the inheritance
{
    @private
    double secondClassCitizen;
}
@end

@implementation MySecondClass
- (id)init {
    if (self = [super init]) {
        // We can access publicNumber because it's public;
        // ANYONE can access it.
        publicNumber = 5;

        // We can access protectedLetter because it's protected
        // and it is declared by a superclass; @protected variables
        // are available to subclasses.
        protectedLetter = 'z';

        // We can't access privateBool because it's private;
        // only methods of the class that declared privateBool
        // can use it
        privateBool = NO;  // COMPILER ERROR HERE

        // We can access secondClassCitizen directly because we
        // declared it; even though it's private, we can get it.
        secondClassCitizen = 5.2;  
    }
    return self;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@interface SomeOtherClass : NSObject
{
    MySecondClass *other;
}
@end

@implementation SomeOtherClass
- (id)init {
    if (self = [super init]) {
        other = [[MySecondClass alloc] init];

        // Neither MyFirstClass nor MySecondClass provided any
        // accessor methods, so if we're going to access any ivars
        // we'll have to do it directly, like this:
        other->publicNumber = 42;

        // If we try to use direct access on any other ivars,
        // the compiler won't let us
        other->protectedLetter = 'M';     // COMPILER ERROR HERE
        other->privateBool = YES;         // COMPILER ERROR HERE
        other->secondClassCitizen = 1.2;  // COMPILER ERROR HERE
    }
    return self;
}

所以为了回答您的问题,@private保护ivars不被任何其他类的实例访问。注意,myfirstclass的两个实例可以直接访问彼此的所有ivar;假设程序员直接完全控制了这个类,他将明智地使用这个能力。


当有人说你不能访问@private实例变量时,理解它意味着什么是很重要的。真正的情况是,如果您试图在源代码中访问这些变量,编译器会给您一个错误。在以前的gcc和xcode版本中,您只会得到一个警告而不是一个错误。

不管怎样,在运行时,所有的赌注都取消了。这些@private@protectedivar可以被任何类的对象访问。这些可见性修饰符只会使将源代码编译成违反可见性修饰符意图的机器代码变得困难。

不要依赖ivar可见性修饰符来保证安全!他们一点也不提供。它们严格用于编译时实现类生成器的愿望。