ユニバーサルiPhoneアプリを作成しようとしていますが、SDKの新しいバージョンでのみ定義されているクラスを使用しています。フレームワークは古いシステムに存在しますが、フレームワークで定義されたクラスには存在しません。
ある種の弱いリンクを使用したいのはわかっていますが、実行時の関数の存在チェックに関するドキュメントを見つけることができます-クラスが存在することを確認するにはどうすればよいですか?
回答:
電流:
if #available(iOS 9, *)
if (@available(iOS 11.0, *))
if (NSClassFromString(@"UIAlertController"))
レガシー:
if objc_getClass("UIAlertController")
if (NSClassFromString(@"UIAlertController"))
if ([UIAlertController class])
これまで、特定のOSバージョンではなく機能(またはクラスの存在)をチェックすることが推奨されていましたが、可用性チェックが導入されたため、Swift 2.0ではうまく機能しません。
代わりにこの方法を使用します。
if #available(iOS 9, *) {
// You can use UIStackView here with no errors
let stackView = UIStackView(...)
} else {
// Attempting to use UIStackView here will cause a compiler error
let tableView = UITableView(...)
}
注:代わりにを使用しようとするobjc_getClass()
と、次のエラーが発生します。
⛔️ 'UIAlertController'はiOS 8.0以降でのみ使用できます。
if objc_getClass("UIAlertController") != nil {
let alert = UIAlertController(...)
} else {
let alert = UIAlertView(...)
}
注objc_getClass()
よりも信頼性がありますNSClassFromString()
かobjc_lookUpClass()
。
if ([SomeClass class]) {
// class exists
SomeClass *instance = [[SomeClass alloc] init];
} else {
// class doesn't exist
}
詳細については、code007の回答を参照してください。
Class klass = NSClassFromString(@"SomeClass");
if (klass) {
// class exists
id instance = [[klass alloc] init];
} else {
// class doesn't exist
}
を使用しNSClassFromString()
ます。が返されたnil
場合、クラスは存在しません。それ以外の場合は、使用可能なクラスオブジェクトを返します。
これはAppleによるとこのドキュメントで推奨されている方法です:
[...]コードは、[a]クラスの存在をテストし、
NSClassFromString()
[the]クラスが存在する場合は有効なクラスオブジェクトを返し、存在しない場合はnilを返します。クラスが存在する場合、コードはそれを使用できます[...]
Class
によって返されたインスタンスを使用してクラスを作成しNSClassFromString
(に割り当てますid
)、そのインスタンスでセレクターを呼び出します。
iOS 4.2以降のベースSDKを使用する新しいプロジェクトの場合、NSObjectクラスのメソッドを使用して、実行時に弱くリンクされたクラスの可用性を確認するという、この新しい推奨アプローチがあります。すなわち
if ([UIPrintInteractionController class]) {
// Create an instance of the class and use it.
} else {
// Alternate code path to follow when the
// class is not available.
}
ソース:https : //developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Using/using.html#//apple_ref/doc/uid/20002000-SW3
このメカニズムは、iOSのほとんどのフレームワークで使用可能なNS_CLASS_AVAILABLEマクロを使用します(NS_CLASS_AVAILABLEをまだサポートしていないフレームワークがある可能性があることに注意してください-これについては、iOSリリースノートを確認してください)。上記のAppleのドキュメントリンクで読むことができる追加の設定も必要になる場合がありますが、この方法の利点は静的な型チェックができることです。
UIAlertController
iOS 7をサポートしながらコードをビルドしようとしたときにこの問題に遭遇しました。code007の答えは正しいですが、必要な追加の構成は、プロジェクトのUIKit を弱くリンクする(からRequired
に設定するOptional
)ものです(少なくともこの状況では)。