バックグラウンド:
iOS 6 SDK を使用してアプリを開発しているとしましょう。展開ターゲットを iOS 5 に設定しています。その後、6 の機能を使用できますが、5 との互換性を維持するために、コードにいくつかのチェックを行う必要があります。
// method only available from 6, class of someObj existed in 5
if (someObj respondToSelector:@selector(aMethod)) {
[someObj aMethod];
}
または
// entire class only available from 6
if (NSStringFromClass([SKStoreProductViewController class]) != nil) {
SKStoreProductViewController *store = [[SKStoreProductViewController alloc] init];
}
ここまでは順調ですね。私が知る限り、これらは物事を行うための標準的な方法です。
しかし、新しいクラスの例について、チェックせずにそのクラスからオブジェクトを割り当て/初期化しようとすると、iOS 5 でクラッシュせず、null が返されることがわかりました。
// run this on an iOS 5 device
NSLog(@"%@", [UICollectionView alloc] init]);
それが iOS 5 でクラッシュを引き起こさないのはなぜですか? これはリンカーの動作に関係していると思いますが、そのバージョンにはそのシンボルが存在しないため、クラッシュが予想されます。
二次的な質問は次のとおりです。通常のテストで NSStringFromClass メソッドを使用する場合、これは +class メソッドを存在しないクラスに送信できることを意味し、null が返されます - なぜ/どのように機能するのでしょうか?
最後に、iOS 6 でのみ定義されたプロトコルを採用する ViewController を作成できることに気付きましたが、これも 5 では問題が発生しません。