実行時にクラスを作成する-NSClassFromString AND objc_getclassがnilを返すのはなぜですか?
質問
両方を使用してみました:
NSClassFromString and objc_getclass
クラスを返すため、実行時に作成できますが、両方の関数は一部のクラス、たとえば" TestClass"に対してnilを返します。 NSClassFromStringは、99%のクラスで機能することに注意してください。
追加する場合
[TestClass class];
NSStringFromClassまたはobjc_getclassを呼び出す前に、動作します。クラス参照を使用してクラスを作成しようとすると、つまり:
[TestClass alloc];
それも機能します。 NSClassFromStringまたはobjc_getclassがnilを返さないように、実行時にクラスを強制的にロードするにはどうすればよいですか?
解決
この同じ問題に遭遇しました。私の場合、
を使用してクラスを検索するコードがありましたClass aClass = objc_getClass("Foo");
FooクラスがAppDelegateと同じプロジェクトバンドルに含まれていたときに機能しました。
コードのリファクタリングの一環として、Fooクラスと関連モデルクラスをAppDelegateプロジェクトから、テストと再利用が容易になる共通の静的ライブラリプロジェクトに移動しました。
FooクラスをlibFooBarに移動すると、objc_getClass(" Foo")はFooクラスの代わりにnilを返しました。
これを解決するために、libFooBarのクラスがObjective-Cランタイムに登録されるように、興味のあるクラスを呼び出しました。次のようにしました:
Foo* foo = [[Foo alloc] init];
[foo release];
Class aClass = objc_getClass("Foo");
今、objc_getClass(" Foo")は、nilの代わりにFooクラスを再び返します。
静的ライブラリ内のクラスの1つが呼び出されるまで、静的ライブラリクラスは登録されないと想定できます。
他のヒント
Objective-Cランタイムリファレンスはここで役立ちます。たとえば、objc_getClassのドキュメントには、「名前付きクラスのClassオブジェクト、またはクラスがObjective-Cランタイムに登録されていない場合はnil」と書かれています。登録の議論を見て回ると、objc_getClassListに次のtidbitがあります。
" Objective-Cランタイムライブラリは、ソースコードで定義されたすべてのクラスを自動的に登録します。実行時にクラス定義を作成し、objc_addClass関数で登録できます。"
(もちろん、objc_addClassは廃止され、objc_allocateClassPairとobjc_registerClassPairは代わりになっているため、ドキュメントは古くなっています。)
これを自分で簡単にしないと、これは怪我の世界のように見えます。アプリの起動時にコードで動的クラスを参照できる可能性はありますか?
ビルド設定にクラス(例:TestClass.m)を手動で追加する必要がありました。ビルドフェーズ>ソースのコンパイル> +> TestClass.m