2012-03-25 7 views
0

superキーワードは、メソッドが最初に定義されているクラスのスーパークラス内のメソッドを検索するようにコンパイラに指示します。たとえば、Class Fatherが[super init]を含むXと呼ばれる新しいメソッドを定義している場合、Class SonでメソッドXを使用します.XはClass Fatherで最初に定義されるため、コンパイラはClass Grandfatherのinitメソッドを検索します。スーパーはObjective-CのNSobjectクラスに常に到達しますか?

私の質問は、変更されていないNSObjectの継承されたメソッドが存在する場合はどうですか?たとえば、superを含むサブクラスで "init"メソッドを使用するとどうなりますか?この場合、initメソッドはまずNSObject自体で定義されます。それはNSObjectを「スキップする」か、それとも上位のクラスがないのでNSObject内のものを実装するだけですか?

-(id)init 
{   
    self=[super init]; 
    //code continues 
} 

答えて

2

superとは、Objective-Cがselfオブジェクトのメソッドを呼び出しますが、superが呼び出されたクラスと同じクラスのメソッドの実装は使用しないことを意味します。やや紛らわしいが、この考えてみます。

@interface Grandparent : NSObject 
- (void)a; 
- (void)b; 
@end 

@implementation Grandparent 
- (void)a {NSLog(@"Grandparent a");} 
- (void)b {NSLog(@"Grandparent b");} 
@end 

@interface Parent : Grandparent 
@end 

@implementation Parent 
- (void)a {NSLog(@"Parent a"); [super a];} 
@end 

@interface Offspring : Parent 
- (void)a {NSLog(@"Offspring a"); [super a];} 
- (void)b {NSLog(@"Offspring b"); [super b];} 
@end 

-[Offspring b]の実装を見てください。それは[super b]を呼び出しますが、Parent-bの実装を提供しません。 Objective-Cは-[Grandparent b]が見つかるまで階層を調べ続け、それを実行します。 Grandparentにこのメソッドがない場合は、NSObjectとなります。

-[Offspring a]を呼び出すことを検討してください。メッセージが記録された後、Parentの実装である[super a]が呼び出されます。そのメッセージは、Parentで定義されているメソッドでそれを実行するため、[super a]を呼び出します。-[Grandparent a](インスタンスは実際にはOffspringオブジェクトですが)が検索されます。

これは、いずれのNSObject子孫に対しても、super経由でメッセージを呼び出すと、メソッドの実装がNSObjectになる可能性があることを意味します。 Objective-CにはNSObject(例えばNSProxy)から派生しないクラスがあるため、superは常にになります。

+0

Xcodeでいくつかの調整をして再度チェックしたところ、「スーパー」は明示的に実装されたメソッドをバイパスするようです。たとえば、Parentが[super a]を行う新しいメソッド "c"を定義して実装していて、main.mで[offspring1 c]を実行すると、superはParentの "a"をバイパスし、 "Grandparent"の "a"をチェックしますたとえParentがOffspringの最初のスーパークラスであっても、私は明示的な実装が "super"を使用する鍵だと思いますか? – Rexroth

+1

@Rexroth私が言ったように、それはメソッドが定義されているクラスのスーパークラスから始まります。あなたの 'c'メソッドは' Parent'で定義されているので、 'super'解像度は' Grandparent'で始まります。 –

+0

したがって、私がOffspringで "c"を再び定義すると、コードが完全に同じであっても、オーバーライドまたは "再定義"とみなされますか?私がOffspringの@implementationで明示的に "c"を実装すると、 "c"が "再定義された"クラスのスーパークラスであるParentクラスから開始されるからです。 – Rexroth

1

あなたはそうです。父も祖父もinitをオーバーライドしていないとしましょうが、あなたのスニペットの実装を使用してSonが行います。 [[aSon alloc] init]を実行すると、[super init]を呼び出すとGrandfatherの実装がinitになりますが、これは見つからず、NSObjectの実装に到達して実行されます。

+0

「スーパー」はありません**実際のオブジェクトのクラスを見てください。 –

+0

違反セグメントが削除されました。 – yuji

+0

downvoteが削除されました。 –

関連する問題