2013-06-19 7 views

答えて

8

あなたは、サブクラスでインスタンス変数を宣言すると、パブリックインターフェイスまたはクラスの拡張であること主張再宣言に関係なく、同じ名前で既存のスーパークラスのインスタンス変数を再宣言しないことを心に留めなければなりません。同じ名前を使用しても、は異なるインスタンス変数です。

これはあなた自身で試すことができます。

@interface Base : NSObject { 
@private 
    int _number; 
} 
@end 

@implementation Base 
- (id)init { self = [super init]; if (self) _number = 10; return self; } 
- (void)logNumber { printf("base = %d\n", _number); } 
@end 

@interface Derived : Base 
@end 

@interface Derived() { 
    int _number; 
} 
@end 

@implementation Derived 
- (id)init { self = [super init]; if (self) _number = 20; return self; } 
- (void)logNumberDerived { printf("derived = %d\n", _number); } 
@end 

int main(void) { 
    Derived *o = [Derived new]; 
    [o logNumber]; 
    [o logNumberDerived]; 
    return 0; 
} 

出力:例えば

base = 10 
derived = 20 

スーパーにおける_numberは、サブクラス(拡張子)で_number異なるからです。うん

s _OBJC_IVAR_$_Base._number 
s _OBJC_IVAR_$_Derived._number 
+0

しかし、おそらく、同じように宣言されている場合、あなたの例は、superで実装されたメソッドで参照されるものがsuperで宣言されたものであることを示しています。サブクラスで宣言されたメソッドで参照されるものは、サブクラスで宣言されたものになりますか? – uchuugaka

+0

@uchuugaka正解。スーパークラスのivarはプライベートなので、サブクラスはそのivarにアクセスすることができず、それ自身の異なるivarしか見ることができません。スーパークラスivarにアクセスするには、(Objective-CランタイムAPIを使用して)余分な努力をする必要があります。 –

+0

が確認されました。私はいくつかのバリエーション、セッター、getters&プロパティでこれをテストし、あなたの言うとおりにできることは確かです。そして、この動作は簡単に "見える"ことができます。ivarは、クラスがivarの親クラスであるオブジェクトです。私は再宣言していると "思っています" ...(そう、私はこの質問にどのように到着したのですか? unsubclassable Cタイプのivarはよりクリアです!) – uchuugaka

3

私はここにまさに私自身に一致する答えを見つけた:彼らはそれは@privateた場合はhttp://lists.apple.com/archives/cocoa-dev/2007/Feb/msg00939.html

、あなたはそれが理由だと を想定しなければならない@protectedありません。その理由は、もちろん単純に、それはあなたが、非常に明確にない可能性は、それが直接 アクセスするにはOKこと、言わないと...

良い理由を 知るまで、すべてが@private作るために賢明だ ているかもしれませんそれが技術的に可能であっても。 はあなたが公開/保護されたインターフェイスに必要な 機能を公開するために、スーパークラスのメンテナを請願しながら行う

安全な事は、独自のクラスで再行うすべてです。

+0

:あなたはnm -aとバイナリ出力のシンボルを調べる場合は、コンパイラは二つの異なるシンボルを生成することがわかります。それはちょっと古くて正式ではなく健全な思考です。興味深いもの: – uchuugaka

関連する問題