[解決済み] Objective-Cの名前空間の衝突を解決する最善の方法は何ですか?
質問
Objective-Cには名前空間がありません。C言語と同じように、すべては1つのグローバルな名前空間の中にあります。例えば、あなたがIBMで働いているならば、"IBM"; Microsoftで働いているならば、"MS"; といった具合に、クラスの前にイニシャルを付けるのが一般的なやり方です。例えば、Adiumはクラスの前に "AI"を付けます(このイニシャルを取るような会社は存在しないため)。Appleは、クラスのプレフィックスにNSをつけ、このプレフィックスはAppleだけのものであると言っています。
ここまでは順調です。しかし、クラス名の前に2文字から4文字を付加することは、非常に、非常に限られた名前空間となります。例えば、MSやAIは全く異なる意味を持つ可能性があり(AIは例えばArtificial Intelligence)、他の開発者がそれらを使って同じ名前のクラスを作るかもしれません。 バング 名前空間の衝突です。
さて、これが自分のクラスと使っている外部フレームワークのクラスの衝突であれば、クラスのネーミングを簡単に変更することができ、大した問題ではありません。 しかし、2つの外部フレームワークを使用し、両方ともソースを持たず、変更もできないフレームワークの場合はどうでしょうか? あなたのアプリケーションはその両方とリンクしており、名前の競合が発生します。これを解決するにはどうしたらいいでしょうか?両方のクラスを使用できるようにするための最良の方法は何でしょうか?
C言語では、ライブラリに直接リンクしない代わりに、dlopen()を使用して実行時にライブラリをロードし、dlsym()を使用して探しているシンボルを見つけ、それをグローバルシンボルに割り当て(好きなように名前を付けることができます)、このグローバルシンボルを介してアクセスすることで回避することができます。例えば、ある C のライブラリが open() という名前の関数を持っているために衝突している場合、 myOpen という名前の変数を定義して、そのライブラリの open() 関数を指すようにします。したがって、システムの open() を使いたいときは open() を使い、他のものを使いたいときは myOpen 識別子を使ってアクセスすることになります。
Objective-Cで同じようなことは可能でしょうか?もし可能でなければ、名前空間の競合を解決するために、他に巧妙でトリッキーな解決策はないのでしょうか?何かアイデアはありますか?
アップデートしてください。
名前空間の衝突を事前に回避する方法や、より良い名前空間を作成する方法を提案する回答は確かに歓迎されますが、私はそれらを 回答 私の問題を解決するものではありませんから。私は2つのライブラリを持っていて、それらのクラス名が衝突しています。私はどちらもソースを持っていないので、変更することはできません。衝突はすでにそこにあり、事前に回避できたかもしれない方法についてのヒントは、もう役に立ちません。私はこれらのフレームワークの開発者にそれらを転送し、彼らが将来より良い名前空間を選択することを望むことができますが、当分の間、私は単一のアプリケーション内で今すぐフレームワークで動作するための解決策を模索しています。これを可能にするために何か解決策がありますか?
解決方法は?
もし、両方のフレームワークからクラスを同時に使用する必要がなく、NSBundleのアンロードをサポートするプラットフォーム(OS X 10.4以降、GNUStepのサポートなし)をターゲットにしていて、パフォーマンスが本当に問題でないなら、そのフレームワークからクラスを使用する必要があるたびに一方のフレームワークをロードし、それからアンロードしてもう一つのフレームワークを使うときにロードすればいいと思います。
最初に考えたのは、NSBundleを使って一方のフレームワークをロードし、そのフレームワーク内のクラスをコピーまたはリネームしてから、もう一方のフレームワークをロードすることでした。これには2つの問題があります。まず、クラスの名前を変更したりコピーするためにポイントされたデータをコピーする関数が見つからず、名前を変更したクラスを参照する最初のフレームワークの他のクラスは、他のフレームワークからクラスを参照するようになります。
IMPが指すデータをコピーする方法があれば、クラスをコピーしたり名前を変えたりする必要はないでしょう。新しいクラスを作成し、IVAR、メソッド、プロパティ、カテゴリをコピーすることができます。はるかに多くの作業が必要ですが、それは可能です。しかし、フレームワーク内の他のクラスが間違ったクラスを参照するという問題はまだ残っています。
EDIT: CとObjective-Cのランタイムの根本的な違いは、私の理解では、ライブラリをロードするとき、ライブラリ内の関数は参照するシンボルへのポインタを含むのに対し、Objective-Cではそのシンボルの名前の文字列表現を持っていることです。したがって、この例では、dlsym を使ってメモリ上のシンボルのアドレスを取得し、それを別のシンボルにアタッチすることができます。元のシンボルのアドレスは変更しないので、ライブラリの他のコードはまだ動作します。Objective-C はクラス名とアドレスの対応付けにルックアップテーブルを使いますが、これは 1-1 の対応付けなので、同じ名前のクラスが 2 つあることはできません。したがって、両方のクラスを読み込むには、どちらかのクラスの名前を変更する必要があります。しかし、他のクラスがその名前のクラスの1つにアクセスする必要がある場合、ルックアップテーブルにそのアドレスを問い合わせることになり、ルックアップテーブルは元のクラスの名前を考えると、名前を変更したクラスのアドレスを返すことはないでしょう。
関連
-
[解決済み] Objective-Cのnil、NIL、nullの違いについて
-
[解決済み] usingディレクティブはネームスペースの内側と外側のどちらを使うべきですか?
-
[解決済み] Objective-Cのtypedef enumとは何ですか?
-
[解決済み] クラス vs. #インポート
-
[解決済み] NSの接頭辞はどういう意味ですか?
-
[解決済み] NSStringにパーセント記号を追加する方法
-
[解決済み】Objective-Cのコードをユニットテストするのに最適な方法は何ですか?
-
[解決済み】NSStringが特定の文字で始まるかどうかを確認する方法
-
[解決済み] Objective-C Runtime: クラスがプロトコルに準拠しているかどうかを確認する最良の方法は?
-
[解決済み] ソリューション内のフォルダはネームスペースと一致させるべきですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] イニシャライザーの要素がコンパイル時定数でない
-
[解決済み] NSTaggedPointerStringをNSStringに変換する。
-
[解決済み] Objective-Cで乱数を発生させる
-
[解決済み] NSの接頭辞はどういう意味ですか?
-
[解決済み] Objective-Cで、オブジェクトの種類をテストするにはどうしたらいいですか?
-
[解決済み] synthesize vs @dynamic、その違いとは?
-
[解決済み] ブロック内の変数をブロック外の変数に代入する
-
[解決済み】UITableViewControllerを使用しないUIRefreshControl
-
[解決済み】セマンティックな問題。プロパティの合成ゲッターは、「所有する」オブジェクトを返すためのCocoa命名規則に従っている。
-
[解決済み】新しい自動リファレンスカウント機構はどのように機能するのですか?