3

私はここで質問を調べて、なぜこの動作が見られるのかについてのヒントを探しましたが、まだ何もありません。


静的ライブラリに組み込まれ、フレームワークバンドルにラップされたクラス(実際には同じ問題を示す2つのクラス)について考えてみます(使用する手順)。それらは、FoundationフレームワーククラスクラスターNSMutableDictionaryおよびNSMutableArray)から継承します。

これらのクラスの使用は、静的関数(クラスメソッドではありません!)を使用してインスタンス(ファクトリヘルパー関数の一種ですか?)を割り当てて初期化する前に、いくつかの静的変数が初期化されることに依存しています。

iOSアプリプロジェクトがそのフレームワークにリンクしている場合、シミュレーターとデバイスの間でObjective-Cランタイムクラスの読み込み動作に違いがあります。

具体的には、デバイス(iPhone 4、iOS 4.3.3)では、アプリがロードされたときにこれらのクラスは+loadメッセージを受け取らず、静的変数は初期化されないため、静的ファクトリメソッドは失敗します。シミュレーターでは、メッセージが送信され、すべてが意図したとおりに機能します。デバイスランタイムに問題がある可能性があります

私の質問は、+loadメッセージが確実に送信されるようにフレームワークを別の方法で構成できるかどうかです。または、iOSでの静的ライブラリ/フレームワーククラスの読み込みに関するバグに遭遇しましたか?


クラスはJSONKitライブラリ(JKArrayJKDictionary)からのものです。

この問題を説明するプロジェクトの例はここにあります– https://github.com/ohhorob/JSONKit-in-framework-demo


編集:@bbumの提案に従って、アプリケーションの実行中にクラスJKDictionaryJKArrayクラスが実際に読み込まれ、使用可能であることを確認しました。DeviceBrokenGitHubプロジェクトのブランチは、使用された検証で更新されます。

Appleにバグレポート(#9461567)を提出しました。

4

2 に答える 2

5

実際に静的ライブラリを作成したのではなく、再配置可能オブジェクトファイルバンドルを作成したため、+loadメソッドは呼び出されません。make-fmwkまたはiOSユニバーサルフレームワークテンプレートのいずれかを使用して静的フレームワークを作成すると、loadメソッドが期待どおりに呼び出されます。

于 2011-05-25T12:47:34.130 に答える
3

奇数; を実行してNSLog(@"klassy klass %@", [MysteryClass class]);、クラスが実際にロードされていることを確認します(ただし、以下を参照してください。これにより、問題が「修正」される可能性があります)。

もしそうなら、これはDYLDローダーのバグです。ファイルしてください。

そうでない場合は、クラスを直接参照するものがないため、リンカーがクラスを削除している可能性があります。[MysteryClass class]アプリのメソッドを追加してみてくださいapplicationDidFinishLaunching:(どこで実行されても、実行されても問題ありません...しかし、それは明らかなスポットです)。

+loadまた、コンストラクター関数を使用せず、代わりに作成することをお勧めします。すなわち:

__attribute__((constructor))
static void initLibrary()
{
    ....
}

これがリンカーの問題である場合、問題が解決する場合と解決しない場合があります。しかし、それはむしろ魔法の+load方法よりもあなたの意図に関してはるかに明確です。

于 2011-05-18T17:17:51.817 に答える