18

私はMacでMarkDalrympleのLearnObjective-Cを読んでいて(プロトコルの章だけなので、まだ比較的新しいです)、何かを理解しようとしています:

なぜクラスを独自の名前で参照するのでしょうか。もし私がというクラスを持っていたらFoo、なぜ私はこう書きたいと思うでしょう、

[[Foo alloc] init]

ではなく

[[[self class] alloc] init]

私がサブクラスのバーを持っていた場合、最初のオプションは私が書くことを無効にしませんか?

[[Bar alloc] init]

2番目のオプションはそれを許可しますか?最初のオプションはいつより良いでしょうか?

4

3 に答える 3

28

通常、クラスメソッド内では、を使用します[[self alloc] init]。たとえば、クラスの便利なメソッドを作成するための標準的な方法は次のとおりです。

+ (id)fooWithBar:(Bar *)aBar
{
    return [[[self alloc] initWithBar:aBar] autorelease];
}

self(クラスメソッドでは、クラスオブジェクトを参照することに注意してください。)

ただし、実際にクラスのインスタンス(サブクラスではない[[Foo alloc] init])が必要な場合は、(つまり、明示的なクラス名)を使用します。Foo

于 2010-08-24T18:35:05.853 に答える
7

そのクラスが必要なときはいつでも、その名前でクラスを参照します。サブクラスがそのクラスから派生した場合、同じメソッド内のselfは、代わりにその派生クラスを表します。したがって、スーパークラスを明示的にインスタンス化する場合は、これを行うことができます。

これが理にかなっている場合があります。そのクラスのインスタンスを返すために、サブクラスにメソッドをオーバーライドするように強制します。または、NSArrayの作成などで使用されるプレースホルダーオブジェクトなど、別のクラスを返すこともできます。

于 2010-08-24T19:41:43.340 に答える
0

[ClassNamealloc]と[selfalloc]が同等ではない条件を見つけました。他の人が同様の状況に直面した場合に備えて、私はそれをリストしています。

//Option 1 
+ (NSInputStream *)streamWBlockWithArray:(NSArray *)dataArray 
{ return [[[self alloc] initWithArray:dataArray] autorelease]; } 
// Option 2 
+ (NSInputStream *)streamBlockWithArray:(NSArray *)dataArray
{ return [[[Block alloc] initWithArray:dataArray] autorelease]; }

オプション1を使用すると、コンパイラーは重複した定義のコンパイラーエラーを出していました。initWithArrayの定義は+[NSArrayinitWithArray]からの定義と競合するものとしてフラグが立てられていました。[selfalloc]を[Blockalloc]に置き換えた後、コンパイラエラーはなくなりました。これはおそらく、コンテキストが十分に明確であるように見えても、曖昧さを解消できないコンパイラにすぎません。

于 2015-10-02T21:21:50.683 に答える