次のようなコードがある場合:
self = [super init]
self は super を指していますか? もしそうなら、なぜあなたはこれが欲しいのですか?インスタンス オブジェクトに変数「someVal」がある場合、[self someVal] を実行してもアクセスできません。正しい?
では、self が super を指している場合、どのようにしてインスタンス変数が self を使用するようになるでしょうか?
次のようなコードがある場合:
self = [super init]
self は super を指していますか? もしそうなら、なぜあなたはこれが欲しいのですか?インスタンス オブジェクトに変数「someVal」がある場合、[self someVal] を実行してもアクセスできません。正しい?
では、self が super を指している場合、どのようにしてインスタンス変数が self を使用するようになるでしょうか?
self は super を指していますか?
それは本当に逆です。super
は実際には と同じですがself
、クラス自体ではなくスーパークラスからメソッドの実装を探し始めるようにコンパイラに指示する点が異なります。super
これは、 の値と の値をログに記録することで確認できself
ます。どちらも同じアドレスを指していることがわかります。
オブジェクトを作成するときは、次のようにします。
Foo *f = [[Foo alloc] init];
はalloc
、作成しているオブジェクトになるメモリを割り当てますが、そのメモリが初期化されるまでは、有効なオブジェクトではなく、単なるメモリのチャンクです。Foo
が のサブクラスでBar
あり、Bar
が のサブクラスである場合NSObject
、慣例により、Foo のイニシャライザは Bar のイニシャライザを呼び出し、Bar のイニシャライザは NSObject のイニシャライザを呼び出すため、初期化は順番に進行します。最初にメモリが NSObjects' によって初期化され-init
、Bar の init が戻り値を受け取ります。に割り当てself
ます。次に、Bar 固有の初期化を実行し、 を返しますself
。次に、 Foo-init
は戻り値をself
再度割り当て、最後に Foo 固有の初期化を行います。
への割り当てはすべて、self
冗長で紛らわしいように思えるかもしれません。これは単なる慣例ですが、その目的は、スーパークラスのイニシャライザが、割り当てられたもの以外のオブジェクトを返せるようにすることnil
です。したがって、たとえば、 の初期化がBar
何らかの理由で失敗した場合、 -[Bar init]
nil が返される可能性があります。nil
が返される可能性[super init]
があるため、self = [super init]
代入を条件内に配置しました。代入された値が のnil
場合、初期化部分はスキップされnil
て返されます。-[Bar init]
作成されたものと同様のオブジェクトが既に存在し、再利用できる場合など、割り当てられたオブジェクト以外のオブジェクトへのポインターを返す可能性もあります。
ほとんどの場合、返されるポインタは から取得した-init
ものと同じ+alloc
であるため、次のように記述できます。
Foo *f = [Foo alloc];
[f init];
ただし、それを書くと、クラスの初期化子とそれが継承するすべてのクラスが常に同じオブジェクトを返し、決して返さないと仮定していますnil
。そうすることで、慣例を破り、自分自身と Foo が継承するクラスを書いた人に深刻な障害を与えることになります.クラスの将来のリリースで別のオブジェクトを返すと、コードが壊れます. また、自分が何をしているのかわからないように見えます。
self は super を指していますか?
この質問は、インスタンス メソッドでは意味がsuper
ありません。具体的/実際のインスタンスへのポインターは実際には存在しないため、スーパークラスの実装を呼び出す必要があることを示しているだけです。そして、ほとんどのオブジェクト (クラス クラスターを除く) の場合、すべてのメソッドreturn self;
の場合、答えはノーです。インスタンスへの実際のポインターは、それ自体で魔法のように変化しません。
記録のために: 例外は、クラス クラスタ (ほとんどの Cocoa コンテナ クラス、たとえば 、 など) によって明示されNSString
ますNSArray
。これらのクラスには多くの場合、最初に割り当てられたものとは異なるインスタンスを返す初期化メソッドがあり、そのクラスは元のクラスの具象サブクラスですself
。たとえば、NSString
イニシャライザの実装は次のようになります。
@implementation NSString
- (NSString *)init
{
[self release];
self = [[__NSCFString alloc] init];
return self;
}
@end
これは、さまざまなタイプの初期化の最適化をこの方法で実現できるためです。
Self は常に 1 つのインスタンスを指しています。super を使用すると、親インスタンスではなく親メソッドを参照しています。
self
現在のクラスのインスタンスを意味します。
self = [super init]
は、self が によって返された値を取得していることを意味し[super init]
ます。