Objective-Cはダックタイピング言語です。これは、実行できることと実行できないことがいくつかあることを意味します。実行できないことの1つは、変数の型への参照を静的に取得することです。
具体的には、あなたの表現では:
[_myArray.class new]
まず、_myArray.classが評価され、次に結果がnewメッセージに送信されます。_myArrayでnil始まるので、も戻ります。また、 _myArray.classreturnsにメッセージを送信するため(またはreturn型が持つゼロに最も近い表現)、メッセージも返されます。これが機能しない理由です。nilnewnilnilnil
あなたはC#のような強く型付けされた言語から来ていると思います。現在実行しているのは、と同等です。これは、値が割り当てられていないため、コンパイルも例外もスローしないため(クラスフィールドかローカル変数かによって異なります)、Foo foo = (Foo)Activator.CreateInstance(foo.GetType())必ず失敗します。foo.GetType()Objective-Cでは、コンパイルされますが、機能しません。必要なのはですがActivator.CreateInstance(typeof(Foo))、ここでもハードコーディングされていることに注意してFooください。したがって、を作成するだけでもかまいませんnew Foo()。
あなたは、コンパイラがオブジェクトの「タイプを知っている」と言います。これは正確には真実ではありません。まず、NSArrayクラスクラスターNSMutableArrayのルートクラスです。NSArrayこれは、両方が抽象であり、サブクラスのインスタンス[NSArray alloc]を[NSMutableArray alloc]返すことを意味します(NSCFArray前回チェックしたとき、そしておそらく他の何か。見たことを思い出します_NSArrayM)。たぶん[NSArray new]うまくいくかもしれませんが、それはあなたに明白なことを与えていませんNSArray。
第二に、型安全性は強制されません。このコードを考えてみましょう:
id foo = @"foo";
NSArray* bar = foo; // no warning!
したがって、コンパイラはそれをであると考えていても、bar実際NSArrayにはNSStringです。コードをプラグインした場合:
id foo = @"foo";
NSArray* bar = foo; // no warning!
NSArray* baz = [bar.class new];
baz今NSStringもです。のランタイムクラスを要求するのでbar、コンパイラは操作とは何の関係もありません。
そして、まさにその種の振る舞いのために、あなたはおそらくあなたが知っているクラスであなたのオブジェクトをインスタンス化するべきです。[NSArray new]_myArraynil