web-dev-qa-db-ja.com

newの代わりにalloc initを使用

Objective-Cを学習し、サンプルコードを読むと、オブジェクトは通常このメソッドを使用して作成されることに気付きます。

SomeObject *myObject = [[SomeObject alloc] init];

の代わりに:

SomeObject *myObject = [SomeObject new];

私はそれらが同等であることを読んだので、これには理由がありますか?

334
willc2

ここには多くの理由があります: http://macresearch.org/difference-between-alloc-init-and-new

選択されたものは次のとおりです。

  • newはカスタム初期化子をサポートしていません(initWithStringなど)
  • alloc-initnewより明示的です

一般的な意見としては、自分が使い慣れているものなら何でも使用すべきだということです。

284
Jeremy Stanley

非常に古い質問ですが、私は楽しみのためにいくつかの例を書いています-多分あなたはそれが役に立つと思うでしょう;)

#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...
136
guitar_freak

+newは、AppleのNSObject実装の+alloc/-initと同等です。これが変わることはほとんどありませんが、あなたのパラノイアレベルによっては、Appleの+newのドキュメントは将来実装の変更(および同等性の破壊)を可能にするようです。このため、「明示的は暗黙的よりも優れている」ため、また歴史的連続性のため、Objective-Cコミュニティは一般的に+newを避けています。ただし、通常、+newを使いこなすことで、Objective-Cに最近来たJavaを見つけることができます。

52
Barry Wark

多くの場合、initに引数を渡す必要があるため、[[SomeObject alloc] initWithString: @"Foo"]などの別のメソッドを使用します。あなたがこれを書くことに慣れているなら、あなたはこのようにそれをする習慣を身につけるので、[[SomeObject alloc] init][SomeObject new]より自然に来るかもしれません。

8
Brian Campbell

1つの短い答えは:

  1. 'new'は基本的な 'init'イニシャライザーでのみ機能し、他のイニシャライザー(たとえば、initWithString :)では機能しません。
  2. .
7
user739711

副次的な注意事項として、どこでも戻り値を使用せずにinitで何かを実行したい場合、個人的に[Foo new]を使用します。 [[Foo alloc] init]の戻り値をどこでも使用しないと、警告が表示されます。多かれ少なかれ、私は[Foo new]を目の保養に使用しています。

3
evdude100

私はこれに非常に遅れていますが、Swiftの世界では、Obj-Cで実際に新しいものは安全ではないことを述べたいと思います。 Swiftは、他の初期化子を作成しない場合にのみ、デフォルトのinitメソッドを作成します。カスタム初期化子を使用してSwiftクラスでnewを呼び出すと、クラッシュが発生します。 alloc/initを使用すると、コンパイラーはinitが存在しないことを適切に訴えます。

3
MurderDev

Newがあなたのために仕事をするなら、それはあなたのコードも控えめに小さくします。コードのさまざまな場所で[[SomeClass alloc] init]を呼び出す場合は、newの実装(つまり、objcランタイム)でホットスポットを作成し、キャッシュミスの数を減らします。

私の理解では、カスタム初期化子を使用する必要がある場合は、[[SomeClass alloc] initCustom]を使用します。

そうでない場合は、[SomeClass new]を使用します。

1
Mike Crawford