8

Apple のドキュメント「Objective-C Programming Language」の 48 ページには、次のように記載されています。

+ (Rectangle *)rectangleOfColor:(NSColor *) color
{
    self = [[Rectangle alloc] init]; // BAD
    [self setColor:color];
    return self;
}

+ (id)rectangleOfColor:(NSColor *)color
{
     id newInstance = [[Rectangle alloc] init]; // GOOD
     [newInstance setColor:color];
     return newInstance;
}


+ (id)rectangleOfColor:(NSColor *)color
{
     id newInstance = [[self alloc] init]; // EXCELLENT
     [newInstance setColor:color];
     return newInstance;
}

一つは悪く、一つは良く、もう一つは優れています。何故ですか?

4

3 に答える 3

17

4つ目のパターンがあります....

(1) 型の不一致は悪いです。

(2) サブクラスで正しく動作しないクラス yield メソッドへの静的参照

(3) クラスへの動的参照は、サブクラスがサブクラス インスタンスとしてインスタンス化されることを意味します。


(4)

+ (instancetype)rectangleOfColor:(NSColor *)color // Über-bestest evar!
{
     Rectangle *newInstance = [[self alloc] init];
     [newInstance setColor:color];
     return newInstance;
}

llvm は、instancetype「yo! このメソッドは、呼び出されたクラスのインスタンスを返します」というキーワードを追加しました。したがって、上記をサブクラス化すると、次のようになります。

RectangleSub *rs = [RectangleSub rectangleOfColor:[NSColor paisleyColor]];

しかし、これは(ひどい色の選択を超えて)警告します:

RectangleSub *rs = [Rectangle rectangleOfColor:[NSColor puceColor]];

(id) 戻り値の型は、2 番目のケースでは警告しません。

newInstanceまた、明示的に型の宣言を切り替えたことに注意してくださいRectangle*。これは、その method のコンテキスト内では、 としてのみ安全に扱うことができるという点でも、より優れてnewInstanceますRectangle*

于 2013-03-15T16:13:27.600 に答える
9
于 2013-03-15T15:59:14.393 に答える
6

In the first case, you assign the self pointer (which should point to the Rectangle class object) to an instance of Rectangle. This is absolutely incorrect.

In the second, you hard code a class to instantiate - Rectangle in this case.

In the third, you allow the class's identity to determine the class of the instance, rather than specifying it explicitly in code. Then, if your Dodecahedron class needs to use this same code, it won't require changing the class name.

于 2013-03-15T15:56:37.293 に答える