Objective-Cを学習し、サンプルコードを読むと、オブジェクトは通常このメソッドを使用して作成されることに気付きます。
SomeObject *myObject = [[SomeObject alloc] init];
の代わりに:
SomeObject *myObject = [SomeObject new];
私はそれらが同等であることを読んだので、これには理由がありますか?
ここには多くの理由があります: http://macresearch.org/difference-between-alloc-init-and-new
選択されたものは次のとおりです。
new
はカスタム初期化子をサポートしていません(initWithString
など)alloc-init
はnew
より明示的です一般的な意見としては、自分が使い慣れているものなら何でも使用すべきだということです。
非常に古い質問ですが、私は楽しみのためにいくつかの例を書いています-多分あなたはそれが役に立つと思うでしょう;)
#import "InitAllocNewTest.h"
@implementation InitAllocNewTest
+(id)alloc{
NSLog(@"Allocating...");
return [super alloc];
}
-(id)init{
NSLog(@"Initializing...");
return [super init];
}
@end
メイン関数の両方のステートメント:
[[InitAllocNewTest alloc] init];
そして
[InitAllocNewTest new];
同じ出力になります:
2013-03-06 16:45:44.125 XMLTest[18370:207] Allocating... 2013-03-06 16:45:44.128 XMLTest[18370:207] Initializing...
+new
は、AppleのNSObject
実装の+alloc/-init
と同等です。これが変わることはほとんどありませんが、あなたのパラノイアレベルによっては、Appleの+new
のドキュメントは将来実装の変更(および同等性の破壊)を可能にするようです。このため、「明示的は暗黙的よりも優れている」ため、また歴史的連続性のため、Objective-Cコミュニティは一般的に+new
を避けています。ただし、通常、+new
を使いこなすことで、Objective-Cに最近来たJavaを見つけることができます。
多くの場合、init
に引数を渡す必要があるため、[[SomeObject alloc] initWithString: @"Foo"]
などの別のメソッドを使用します。あなたがこれを書くことに慣れているなら、あなたはこのようにそれをする習慣を身につけるので、[[SomeObject alloc] init]
は[SomeObject new]
より自然に来るかもしれません。
1つの短い答えは:
副次的な注意事項として、どこでも戻り値を使用せずにinitで何かを実行したい場合、個人的に[Foo new]
を使用します。 [[Foo alloc] init]
の戻り値をどこでも使用しないと、警告が表示されます。多かれ少なかれ、私は[Foo new]
を目の保養に使用しています。
私はこれに非常に遅れていますが、Swiftの世界では、Obj-Cで実際に新しいものは安全ではないことを述べたいと思います。 Swiftは、他の初期化子を作成しない場合にのみ、デフォルトのinitメソッドを作成します。カスタム初期化子を使用してSwiftクラスでnewを呼び出すと、クラッシュが発生します。 alloc/initを使用すると、コンパイラーはinitが存在しないことを適切に訴えます。
Newがあなたのために仕事をするなら、それはあなたのコードも控えめに小さくします。コードのさまざまな場所で[[SomeClass alloc] init]
を呼び出す場合は、newの実装(つまり、objcランタイム)でホットスポットを作成し、キャッシュミスの数を減らします。
私の理解では、カスタム初期化子を使用する必要がある場合は、[[SomeClass alloc] initCustom]
を使用します。
そうでない場合は、[SomeClass new]
を使用します。