respondsToSelector但选择器无法识别

ima*_*747 11 selector ios

我在关于如何在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)];
}
Run Code Online (Sandbox Code Playgroud)

它返回true给响应者选择器,因此尝试执行选择器,此时它崩溃,因为选择器不存在...为什么我得到一个对不存在的选择器的肯定响应?

rob*_*off 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
}
Run Code Online (Sandbox Code Playgroud)


Eli*_*iot 5

我也被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
}
Run Code Online (Sandbox Code Playgroud)

基于此示例,如果您愿意,可以将其写入单个分支中,然后检查对象是否为零:

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