Objective-Cを学び、サンプルコードを読むと、オブジェクトは通常、このメソッドを使用して作成されていることがわかります。
SomeObject *myObject = [[SomeObject alloc] init];
の代わりに:
SomeObject *myObject = [SomeObject new];
私はそれらが同等であると読んだので、これには理由がありますか?
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
一般的な意見としては、使い慣れたものを使用する必要があるようです。
+newWithString:
すでに実装して-initWithString
いる場合でも、実装を妨げるものは何もありません。それほど一般的ではありません。個人的にnew
はinit
、指定されたイニシャライザがの場合は常に使用しています。
+newWithString:
。それは懸念の分離を壊します。-init
とにかく使いたいだけの場合は、を使わない理由はありません+new
。
[[NSString alloc] initWithFormat:...]
と[NSString stringWithFormat:...]
は両方とも同等です。Appleは懸念の分離に違反していて、このように実装すべきではないと言っていませんか?(注:私は軽蔑するつもりはありません。詳細を知りたいのですが、Appleのリードに従うのが悪い考えであるかどうかを知りたいと思います。)
非常に古い質問ですが、楽しみのためにいくつかの例を書きました—多分あなたはそれが役に立つと思うでしょう;)
#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...
[[InitAllocNewTest alloc] init]
んがコンパイルされ[InitAllocNewTest new]
ません。(改行の欠如などの謝罪)
+new
+alloc/-init
AppleのNSObject
実装と同等です。これが変更される可能性はほとんどありませんが、あなたのパラノイアレベルによっては、Appleのドキュメント+new
が将来の実装の変更(および同等性の破壊)を可能にするようです。このため、「明示的なものは暗黙的なものよりも優れている」ため、歴史的な継続性のため、Objective-Cコミュニティは一般的にを避けてい+new
ます。ただし、通常、Objective-Cへの最近のJavaの参入者は、を使いこなすことで見つけることができ+new
ます。
+new
。なぜなら、NeXTの時代から存在していたからです。+new
何かがずっと前にobjcを学んだ誰かのしるしであるなら、この言語に慣れた人、あるいは何年も書いてきたが、iOSブームの後に明らかにそれを理解している多くの人が、どういう+new
意味か分からないようです。第2に、+new
非常に古く、次の時代から、Appleは古いコードを壊すような方法で変更するのは非常に気が狂います。
new
イディオムはSmalltalkから来ていると確信しています。Rubyでも使用されており、Objective-CとRubyの両方は、Smalltalkから多くの構文と規則を派生させています。
多くの場合、引数を渡す必要があるinit
ため、などの別のメソッドを使用し[[SomeObject alloc] initWithString: @"Foo"]
ます。あなたがこれを書くことに慣れているなら、あなたはこのように書く習慣を身につけるので、[[SomeObject alloc] init]
より自然に来るかもしれません[SomeObject new]
。
短い回答者は次のとおりです。
newがあなたのために仕事をするなら、それはあなたのコードを適度に小さくします。それ以外の方法で[[SomeClass alloc] init]
コード内のさまざまな場所で呼び出す場合は、新しい実装、つまりobjcランタイムでホットスポットを作成し、キャッシュミスの数を減らします。
私の理解では、カスタム初期化子を使用する必要がある場合 [[SomeClass alloc] initCustom]
。
そうでない場合は、を使用してください[SomeClass new]
。
init
関数をオーバーライドして使用し[[SomeClass alloc] init];
ます。パラメータが必要な場合でも、そのようなことをしないでください[[SomeClass alloc] initWith:...];
。最後に、init
関数をカスタム実装でオーバーライドする場合new
、オブジェクトの作成時に呼び出すことができますが、それでもカスタムinit
実装が呼び出されます。