问题 respondsToSelector但选择器无法识别


我在关于如何在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给响应选择器,因此尝试执行选择器,此时它崩溃,因为选择器不存在...为什么我得到一个不存在的选择器的肯定响应?


8268
2017-09-16 21:11


起源

我不确定你为什么要在主捆绑上调用该方法。我想也许你打算在另一个对象上调用它。你能链接到你引用的样本吗? - RyanR
docs.huihoo.com/apple/wwdc/2013/... - ima747


答案:


我也被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
}

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

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

5
2017-11-13 19:49





的文档 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
}

7
2017-09-16 22:14



我试图避免实施直接版本检查,特别是因为Apple在其关于实现appStoreReceiptURL的教程中明确指出不要这样做,但这似乎是唯一的方法。作为参考,我跟随WWDC会议,幻灯片可用于 docs.huihoo.com/apple/wwdc/2013/... - ima747


我看到了 WWDC 2013谈话(例如,“使用收据保护您的数字销售”) 太。和中的冲突声明 appStoreReceiptURL文档。似乎appStoreReceiptURL的WWDC 2013代码示例未经测试。


1
2017-10-19 19:24