Objective-Cはダックタイピング言語です。これは、実行できることと実行できないことがいくつかあることを意味します。実行できないことの1つは、変数の型への参照を静的に取得することです。
具体的には、あなたの表現では:
[_myArray.class new]
まず、_myArray.class
が評価され、次に結果がnew
メッセージに送信されます。_myArray
でnil
始まるので、も戻ります。また、 _myArray.class
returnsにメッセージを送信するため(またはreturn型が持つゼロに最も近い表現)、メッセージも返されます。これが機能しない理由です。nil
new
nil
nil
nil
あなたは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]
_myArray
nil