respondsToSelector但选择器无法识别

时间:2013-09-16 21:11:58

标签: ios selector

我正在关注苹果的示例代码,以了解如何在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给响应选择器,因此尝试执行选择器,此时它崩溃,因为选择器不存在...为什么我得到一个不存在的选择器的肯定响应?

3 个答案:

答案 0 :(得分:7)

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
}

答案 1 :(得分:5)

我也被WWDC会话中给出的错误示例代码所困扰。看起来Apple已使用new reccomended sample code更新了他们的文档:

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 :(得分:1)

我也在WWDC 2013 talk (e.g., “Using Receipts to Protect Your Digital Sales”)看到了这一点。以及the appStoreReceiptURL docs中的冲突陈述。似乎appStoreReceiptURL的WWDC 2013代码示例未经测试。