ОтвечаетSoSlector, но селектор не распознается

Я следую примеру кода примера яблока в письме о том, как реализовать проверку чека в iOS 7, и он работает, за исключением случаев, когда я запускаю следующий код (взятый в основном дословно из их примера) под iOS 6

NSBundle *bundle =[NSBundle mainBundle];
if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) { // can do local device receipt validation
    NSURL *receiptURL = [bundle performSelector:@selector(appStoreReceiptURL)];
}

Он возвращает true для ответов на селектор и поэтому пытается выполнить селектор, в котором он сработает, потому что селектор не существует... Почему я получаю положительный ответ на селектор, который не существует?

Ответ 1

Я также был укушен неправильным образцом кода, приведенным на сессии WWDC. Похоже, Apple обновила свою документацию с помощью нового рекомендуемого примера кода:

if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
   // Load resources for iOS 6.1 or earlier
} else {
   // Load resources for iOS 7 or later
}

Основываясь на этом примере, вы можете записать его в одной ветки, например, если хотите, а затем проверить, если объект равен нулю:

NSURL* url = nil;
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
    //iOS 7 or later, safe to use appStoreReceiptURL
    url = [[NSBundle mainBundle] performSelector:@selector(appStoreReceiptURL)];
}

Ответ 2

Документация для appStoreReceiptURL объясняет, что этот метод существовал как частный метод перед iOS 7 и что его реализация до iOS 7 вызывает doesNotRecognizeSelector:. Поэтому вы не можете использовать respondsToSelector:, чтобы проверить, нормально ли вызывать этот метод.

Вместо этого вам нужно проверить версию системы:

NSString *version = [UIDevice currentDevice].systemVersion;
if ([version compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) {
    // safe to use appStoreReceiptURL
} else {
    // not safe to use appStoreReceiptURL
}