2009-05-10 9 views

答えて

183

それは@privateとして宣言されたインスタンス変数は、同じクラスののインスタンスにアクセスできることを意味し-it 可視性修飾子です。プライベートメンバーには、サブクラスや他のクラスからアクセスすることはできません。例えば

:また

@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で常に公開されています。メソッドの宣言を「隠す」方法がありますが、詳細はthis questionを参照してください。

+0

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

+0

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

160

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は、他のクラスのインスタンスによってアクセスからアイバーズを保護します。 MyFirstClassの2つのインスタンスは、他のすべてのivarsに直接アクセスできます。プログラマがこのクラスを直接完全に制御できるので、彼はこの能力を賢明に使うと考えられます。

+19

Objective-Cでは@public、@proteced、および@privateを使用することは珍しいことです。推奨されるアプローチは、常にアクセサを使用することです。 –

+0

BJ、これは私が見たこの質問に対する最も簡潔で有用な回答です。非常によく置く。 – MikeyWard

+1

@Georg、しかしあなたが制限付きの可視性であなたのivarsをマークしない限り、どのようにアクセサーの使用を強制しますか? –

13

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

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

セキュリティのためにivar可視性修飾語を使用しないでください!彼らはまったく何も提供しません。厳密に言えば、クラスビルダーの望みをコンパイル時に強制することです。

関連する問題