这在iOS8中运行良好,但是当我把它放在iOS7设备上时,崩溃会给我带来错误
-[UIApplication registerUserNotificationSettings:]: unrecognized selector sent to instance 0x14e56e20
我正在AppDelegate
注册通知:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#ifdef __IPHONE_8_0
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
#else
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
#endif
application.applicationIconBadgeNumber = 0;
return YES;
}
当我设置断点时,它始终运行__IPHONE_8_0
块中的代码。我怎么能检测到哪个块运行?
答案 0 :(得分:5)
您不应该像这样使用预处理器。更好的方法是检查您的对象是否响应您发送的消息,而不是检查操作系统版本。将您的方法更改为
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
}
else
{
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
application.applicationIconBadgeNumber = 0;
return YES;
}
这里有几点需要注意。我将[UIApplication sharedApplication]
更改为application
,因为委托已经在您的UIApplication
实例中传递,因此只需直接访问它即可。
respondsToSelector:
是来自NSObject
的方法,它会告诉您接收方application
是否会响应选择器(或方法)。你只需要像@selector(myMethod:)
那样包装方法来检查它。在使用较新的API时,这是一种很好的做法,可以实现向后兼容性。在处理id
类型的匿名对象时,您还希望进行此类检查。
至于#ifdef __IPHONE_8_0
无效的原因,请查看以下答案:https://stackoverflow.com/a/25301879/544094
答案 1 :(得分:2)
#ifdef __IPHONE_8_0
是编译时指令。因为您的编译目标通常是最新的iOS版本,所以这将始终是编译到您的应用程序中的代码。这与应用程序运行的设备无关,因为它是在应用程序存在之前完成的(因此肯定在应用程序运行之前)。
相反,您应该使用运行时检查。您可以查看iOS版本,或者您可以检查是否存在您尝试使用的方法:
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings)]) {
// Do iOS8+ stuff.
} else {
// Do iOS7- stuff.
}