web-dev-qa-db-ja.com

フレームワークを「ウィークリンク」するとはどういう意味ですか?

Xcodeでは、フレームワークを「必須」ではなく「オプション」に設定できます。これは、フレームワークが弱くリンクされていることを意味します。

フレームワークは、どこかにインポートされたときにのみバンドルに含まれるという意味ですか?

プライベートAPIを使用するいくつかのデバッグフレームワークを弱くリンクしたいのですが、それらをAppStoreビルドに表示したくありません。

21
openfrog

重要な注意:この回答はiOS8が発表される前に書かれました。技術的な詳細は引き続きシステムフレームワークに適用されますが、アプリバンドル内で出荷される独自の動的にリンクされたフレームワークを構築できるようになりました。制限があります。たとえば、アプリとその拡張機能のみが埋め込みフレームワークの同じインスタンスにリンクできますが、iOS 8以降、カスタムの動的にリンクされたフレームワークが可能であるという事実は変わりません。 。詳細については、 このガイド組み込みフレームワークを使用したコードの共有)およびWWDC 2014セッション416最新のフレームワークの構築

元の回答:(プラットフォーム)フレームワークのどれも実際には「バンドルに含まれていません」。代わりに、「バイナリとライブラリのリンク」ビルドフェーズに追加すると、アプリにはフレームワークへの参照( "link")があります。フレームワークはデバイスにプリインストールされています。アプリを実行すると、アプリのすべてのフレームワーク参照が(デバイス上の)ダイナミックリンカーによって解決されます。つまり、アプリが使用できるようにフレームワークコードが読み込まれます。

一部のフレームワークは、サポートする予定のすべてのデバイスで使用できない場合があります。たとえば、PassKitはiOS 6で導入されました。iOS5デバイスでPassKitに対してリンクするアプリを実行すると、動的リンカーができないため、起動直後にクラッシュします。デバイス上のフレームワークを見つけます。ただし、PassKitをウィークリンクすると、フレームワークが見つからなかった場合、ダイナミックリンカーはすべてのフレームワークのシンボルをnilに設定します。これにより、アプリがクラッシュするのを防ぎ、実行時にシンボルの可用性を確認できます。例:

if ([PKPass class]) {
  // Class is available - use it
  PKPass *pass = [[PKPass alloc] init];
}

[PKPass class]はすべてのデバイス/システムで安全に使用できます。古いシステムではPKPassクラスシンボルがnilになり、Objectiveではメッセージングnilは問題にならないためです。 -C。

ウィークリンクの詳細: Appleドキュメント

あなたの質問に本当に答えるには:

それは、フレームワークがどこかにインポートされたときにのみバンドルに含まれることを意味しますか?

いいえ。フレームワークは常にアプリからリンクされます。アプリが実行されている実際のデバイスでフレームワークが見つからない場合にのみ、フレームワークはロードされません。

1つの解決策は、デバッグビルドとAppStoreビルドに別々のターゲットを設定することです。別の方法は、Xcodeの組み込みの「バイナリとライブラリのリンク」ビルドフェーズを使用せず、リンカーオプションを介してデバッグフレームワークをリンクすることです。これらは、次のように、構成(Debug/Release/...)ごとに個別に指定できます。

Adding framework via linker flags

弱くリンクしたい場合は、代わりに-weak_framework PassKit(もちろん、PassKitはここでの単なる例です...フレームワークの名前を挿入してください)を使用してください。デバッグフレームワークがデフォルトのフレームワークディレクトリの1つにない場合は、フルパスを指定するか、フレームワークの検索パスを変更する必要があります。さらに、おそらくマクロを使用して、デバッグフレームワークを使用するコードがAppStoreビルドに到達しないようにする必要があります。

編集:Xcode 5以降のもう1つのオプションは、@import <FrameworkName>;を使用することです。このようにして、「Link Binary ...」フェーズを空のままにして、コード内のフレームワークのリンクをトリガーできます。次に、DEBUGなどのマクロを使用して、一部のフレームワークがAppStoreのビルドに使用されていないことを確認できます。 @importに関して 優れた回答 があります。

18
hagi

IAdsを使用しているときに弱いリンクに遭遇しました。問題は、iAdsフレームワークを強力にリンクし、iAdsをサポートしていないSDKを備えたデバイスでアプリを実行すると、単にクラッシュすることでした。クラッシュを回避するために許可された弱いリンク。リンクが弱い場合でも、フレームワークが利用可能かどうかをコードでチェックインする必要があると私は信じています。

3
azamsharp

それは、フレームワークがどこかにインポートされたときにのみバンドルに含まれることを意味しますか?

これは、スキームまたはターゲットをどのように構成したかによって異なります。

1つのスキームをデバッグにのみ使用し、オプションのフレームワークをそこにのみ含めることができます。リリース用のオプションのフレームワークなしで別のスキームを使用します。

Scheme Example

[〜#〜]更新[〜#〜]

これを行うには、プロジェクト構成に基づいて新しいスキームを作成し、 hagiの回答 の説明に従ってOTHER_LDFLAGSを設定します。

Project Configurations and Schemes

2
mkalmes