1. ホーム
  2. ios

[解決済み] 弱いリンク - クラスが存在するかどうかを確認し、そのクラスを使用します。

2023-04-04 14:32:06

質問

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

何らかの弱いリンクを使用したいことは分かっていますが、私が見つけたどのドキュメントも、関数の存在に対する実行時チェックについて話しています。

どのように解決するのですか?

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])

Swift 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が推奨している方法です。 この文書 :

[...] あなたのコードは クラスが存在するかどうかを NSClassFromString() これは もしクラスが存在すれば、有効なクラスオブジェクトを が存在する場合は有効なクラスオブジェクトを、存在しない場合はnilを返します。もし クラスが存在する場合、あなたのコードはそれを使用することができます [...]