Objective-c オブジェクトを動的に割り当てる必要があるのはなぜですか? スタック上に作成できる C++ とは異なり、オブジェクトへのポインターにする必要があるのはなぜですか? ありがとう。
3 に答える
主な理由: 予約するスタックサイズがわからない。
また、既存の慣例や使用法により、制限を解除することは非常に困難です。
この場合、初期化時に正しい「vtable」を設定するのは簡単なので、動的メッセージングは重要ではありません。
C++ では、スタック オブジェクトのサイズは常にわかっています (サイズが間違っていれば、何が起こるかがわかります)。objc の alloc/init シーケンスは、いくつかの型のいずれかを返すことができます-それぞれが異なるサイズ (本質的にはファクトリです) を持つか、まったく何も返しません。
サイズも実行時に変化する可能性があります (たとえば、実行時にクラスにフィールドを追加できます)。
更新 1
私はこれに興味があったので、概念実証として小さなテスト プログラムを作成しました。
私は単純なスタック ベースの objc クラス階層を実装することができました。これはNSObject
のインターフェイスのかなりの部分も実装しました。いずれにせよ、私の単純なクラス階層はNSObject クラスまたはプロトコルと完全に互換性がありませんでした。したがって、スタック ベースの objc オブジェクトが本当に必要な場合は、これを実現することができます (特に難しいことではありません)。
スタック スペースを確保するために、C++ とは異なることを行う必要はありません。予約するスタック サイズは、一部の領域ではまだ制限されています (ファクトリ メソッド、クラス クラスターなどを考慮してください)。
デフォルトでは機能しないランタイム機能もいくつかあります。ここでの最良の例は、実行時に ivar を追加する機能です。必要に応じて、実際にこの機能に対応できます。私はその運動を気にしませんでした。
当然のことながら、基本インターフェイスにはいくつかの変更が加えられる可能性があります。私が楽しみのために作成した変更の 1 つは、生きているオブジェクトの実装 (型) を交換する機能を追加することでした。
楽しんで
更新 2
結局のところ、GCC は私が書いた概念実証を受け入れています。残念ながら、これは、正しいサイズを確保する際に発生する可能性がある問題/危険性のため、clang で禁止されています (言語の動的機能を考慮すると...)。例: clang は禁止しsizeof(NSObject)
ます。しかたがない。
Objective-c は動的言語です。つまり、実行時にすべてが変更される可能性があります。オブジェクトのクラス オブジェクトは、実行可能ファイルからロードされたときにのみ作成され、カテゴリによって変更できます。また、ランタイムはプロパティの変数をインスタンス化できます。オブジェクトはコンパイル後に変更される可能性があるため、使用するまで作成できません。
これは、Objective-C が動的バインディングまたは遅延バインディングを使用する方法によるものです。クラスの関数をそのオブジェクトによって呼び出すか、同じクラスまたはスーパークラスのポインターを介して呼び出すかを常に選択できる C++ とは異なります。後者の場合、ポリモーフィズムが必要です。
ただし、Objective-C では、実行時に正しい関数を決定する機能が常に存在します。違いは、たとえば C++ では、使用されている関数が存在することをコンパイラが確認する必要があるのに対し、Objective-C ではコンパイラは実際には気にせず、ランタイム システムのみが決定することです。