88

ユニバーサル iPhone アプリを作成しようとしていますが、SDK の新しいバージョンでのみ定義されたクラスを使用しています。フレームワークは古いシステムに存在しますが、フレームワークで定義されたクラスは存在しません。

ある種の弱いリンクを使用したいことはわかっていますが、関数の存在のランタイムチェックについて話しているドキュメントを見つけることができます-クラスが存在することを確認するにはどうすればよいですか?

4

2 に答える 2

165

TLDR

現時点の:

  • スウィフトif #available(iOS 9, *)
  • Obj-C、iOS :if (@available(iOS 11.0, *))
  • Obj-C、OS X :if (NSClassFromString(@"UIAlertController"))

遺産:

  • Swift (2.0 より前のバージョン) :if objc_getClass("UIAlertController")
  • Obj-C、iOS (4.2 より前のバージョン) :if (NSClassFromString(@"UIAlertController"))
  • Obj-C、iOS (11.0 より前のバージョン) :if ([UIAlertController class])

スイフト 2+

歴史的には、特定の 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 以降でのみ使用できます。


以前のバージョンの Swift

if objc_getClass("UIAlertController") != nil {
    let alert = UIAlertController(...)
} else {
    let alert = UIAlertView(...)
}

はまたはobjc_getClass() より信頼性が高いNSClassFromString()objc_lookUpClass()ことに注意してください。


Objective-C、iOS 4.2+

if ([SomeClass class]) {
    // class exists
    SomeClass *instance = [[SomeClass alloc] init];
} else {
    // class doesn't exist
}

詳細については、code007 の回答を参照してください


OS X または以前のバージョンの iOS

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 を返します。クラスが存在する場合、コードはそれを使用できます [...]

于 2010-06-16T21:31:14.093 に答える
69

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のドキュメントリンクで読むことができる追加の設定構成も必要になる場合がありますが、この方法の利点は、静的な型チェックを取得できることです。

于 2012-04-09T01:41:49.233 に答える