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/-initAppleの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実装が呼び出されます。