2

Objective C との C++ の違いに関するこのページを見ていると、次のように述べられています。

Objective C の動的な性質により、実行時に既存のクラスを拡張できます。Objective C では、既に作成したオブジェクトに関連する拡張機能のセットであるカテゴリを定義できます。たとえば、テキストベースのアプリをグラフィックス アプリに変換する場合、オブジェクトが自分自身を描画するために必要なコードをカテゴリとしてコンパイルし、必要な場合にのみ実行時に読み込むことができます。これによりメモリが節約され、元のオブジェクトを変更せずに残すことができます。

現在、私はカテゴリに精通しており、それらを使用していますが、動的ローディングにどのようにつながるかわかりません。カテゴリ ファイルの場合import、カテゴリ メソッドを使用するかどうかに関係なく、そのクラスを使用するたびにメモリを消費して、それが拡張するクラスと共にコンパイルされませんか?

4

2 に答える 2

1

実行時にバンドル/プラグイン/フレームワークをロードできます。これは、引用が参照する Objective-c の動的な性質です。カテゴリに固有のものではありません。

ただし、ロードする (コンパイルされた) コードに既存のクラスのカテゴリが含まれている場合、拡張機能は、最初からそこにあったかのように機能します。つまり、クラスはコンパイル時に「凍結」されておらず、バンドル/プラグイン/フレームワークをロードすることは、実行時に既存のクラスに新しいメソッドを追加する 1 つの方法です。

これにより、他の C ベースのコンパイル済み言語と比較して、プラグイン アーキテクチャを実装したり、アプリの起動時間を短縮したり、メモリ フットプリントを抑えたりするために必要な場合にのみコードをロードすることが比較的簡単になります。

于 2012-11-15T08:40:12.773 に答える
0

カテゴリを含む静的ライブラリとリンクすると、リンカーはすべてのカテゴリ コードを実行可能ファイルにコピーします。共有ライブラリとリンクすると、共有ライブラリのコード セグメント全体がプロセスのアドレス空間にマップされますが、遅延してページインされるため、すべてを使用しない限り、ディスクからすべてのカテゴリ コードを実際に読み取ることはできません。

しかし、それは実際にはこのページが話していることではないと思います。

リンク時ライブラリ

まず、アプリをリンクするようにリンカーに指示するライブラリについて説明します。

を考慮してくださいNSString。このNSStringクラスは、Foundation フレームワークで定義されます。これは、GUI を持つプログラムと GUI を持たないプログラムで役立つ汎用クラスでいっぱいのフレームワークです。そのためNSString、Foundation で定義されているクラスには、文字列をグラフィックス コンテキストに描画するためのコードが含まれていません。そのコードは (通常) 非 GUI アプリでは役に立たないからです。

AppKit フレームワーク (OS X 上) は GUI を管理します。GUI で文字列をグラフィック コンテキストに描画できると便利です。そのため、AppKit には、文字列を描画するためのメソッドを追加するカテゴリ onNSStringdrawAtPoint:withAttributes:が含まれています。UIKit (iOS 上) は同じことを行います (ただし、メソッドは少し異なります)。

したがって、OS X でプログラムを作成し、Foundation を使用するが AppKit を使用しない場合、プロセスは AppKitNSStringカテゴリをロードせず、 NSString.

AppKit のような共有ライブラリの場合、最新のハードウェアでは価格はごくわずかです。

これで、静的にすることができる独自のライブラリで同じことができます。Twitter と対話するための「TwitterModel」ライブラリを作成するとします。アカウントやつぶやきなど、Twitter で見つけたものをモデル化するクラスがたくさんあります。ただし、ツイートを表示するための GUI を管理するためのコードは含まれていません。

代わりに、別のライブラリ「TwitterGUI」を作成します。これは、(さらに多くのクラスを定義することに加えて) カテゴリを使用して、「TwitterModel」ライブラリのモデル クラスにメソッドを追加します。

TwitterGUI と TwitterModel の両方にリンクするプログラムを作成すると、実行可能ファイルには両方のライブラリのすべての Objective-C コードが含まれます。ただし、コマンド ラインのみのプログラム (GUI なし) を作成し、それを TwitterModel にリンクするだけの場合、そのプログラムには GUI 関連のコードは含まれません。ああ、節約!

ランタイム ライブラリ

次に、リンカーにアプリをリンクするように指示しない共有ライブラリについて考えてみましょう。

dlopenまたはのような API を使用して、実行時に新しいコードをプロセスに動的にロードできます-[NSBundle load]。ライブラリにカテゴリが含まれている場合、それらのカテゴリは実行中のプログラムのクラスに追加されます。

そのため、ユーザーがアプリを実行するときにユーザーのシステムに共有ライブラリが存在する場合は、ライブラリをプログラムで読み込もうとすることで、オプションでアプリに共有ライブラリを使用させることができます。成功した場合は、ライブラリで定義されていることがわかっている任意のカテゴリ メソッドを呼び出すことができます。(もちろん、ライブラリが提供するクラスがあればそれを使用できます。) ライブラリのロードに失敗した場合は、ライブラリからこれらのカテゴリ メソッドを呼び出さないように注意してください。

ただし、通常、動的読み込み API を使用してプラグインを読み込みます。プラグインは、基本クラスをサブクラス化するクラス、またはプラグインが実装するために特別に定義したプロトコルに準拠するクラスを提供します。そのクラスの名前を取得する必要があるだけで、そのインスタンスを作成し、基本クラスまたはプロトコルで定義したメッセージを送信します。

于 2012-11-15T08:57:18.077 に答える