Objective-Cで「@private」はどういう意味ですか?


回答:


186

これは可視性修飾子です。つまり、同じクラスのインスタンス@privateのみがアクセスできるように宣言されたインスタンス変数です。プライベートメンバーは、サブクラスや他のクラスからアクセスできません。

例えば:

@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ではメソッドは常にパブリックです。ただし、メソッド宣言を「隠す」方法はいくつかあります。詳細については、この質問を参照してください。


@implementationの後の括弧内にあるインスタンス変数はどうですか?彼らはいつもプライベートですか?
ジョンヘンケル2014

私はそれが古いことを知っています...しかし、それは可視性修飾子ではありません。これはアクセス修飾子です。これはC ++ではより重要な違いですが、Objective-Cでも違いがあります。変数はコンパイラに表示されます。コンパイラーはそれにアクセスさせません。
gnasher729 2014年

161

htwが言ったように、それは可視性修飾子です。 @privateつまり、ivar(インスタンス変数)に直接アクセスできるのは、同じクラスのインスタンス内からのみです。しかし、それはあなたにとってあまり意味がないかもしれませんので、例を挙げましょう。init簡単にするために、クラスのメソッドを例として使用します。インラインでコメントして、関心のある項目を指摘します。

@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

@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;
}

@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はivarを他のクラスのインスタンスによるアクセスから保護します。MyFirstClassの2つのインスタンスが互いのすべてのivarに直接アクセスできることに注意してください。プログラマはこのクラスを直接完全に制御できるため、この機能を賢く使用することが想定されています。


20
Objective-Cで@ public、@ proteced、@ privateを使用することは一般的ではないことを述べておく必要があります。推奨されるアプローチは、常にアクセサーを使用することです。
GeorgSchölly、2009年

1
@Georgですが、可視性が制限されたivarをマークしない限り、アクセサーの使用をどのように強制しますか?
Greg Maletic、2010年

5
@GeorgSchölly:xcode 4.x +は自動的に@privateオブジェクトのテンプレートを挿入するので、もはやそれほど珍しいことではありません。
dawg

1
@Georg @ private、@ protectedは継承が関係する場合に使用できますが、個人的には使用していません:)
chunkyguy

5
最近では、インスタンス変数をパブリックヘッダーに配置する理由はほとんどありません。それらは@implementationブロックに直接置くことができます。そして、一度それを実行すると、可視性修飾子に関係なく、それらはそのファイルの外部の誰にも見えないため、事実上プライベートになります。
BJホーマー、

14

@privateインスタンス変数にアクセスできないと誰かが言ったときの意味を理解することが重要です。実際の話は、ソースコードでこれらの変数にアクセスしようとすると、コンパイラーがエラーを表示するということです。以前のバージョンのGCCとXCodeでは、エラーではなく警告が表示されるだけでした。

いずれにせよ、実行時には、すべてのベットがオフになっています。これら@private@protectedivarには、任意のクラスのオブジェクトからアクセスできます。これらの可視性修飾子は、ソースコードを可視性修飾子の意図に違反するマシンコードにコンパイルすることを困難にします。

セキュリティのためにivar可視性修飾子に依存しないでください!彼らは何も提供しません。これらは、クラスビルダーの希望をコンパイル時に強制するためのものです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.