事实证明,由于AnyObject是id的精神继承者,因此您可以在AnyObject上调用任何消息。这相当于向id发送消息。好,可以。但是现在我们添加了一个概念,即所有方法在AnyObject上都是可选的,并且我们可以使用某些方法。
鉴于以上所述,我希望可以将UIApplication.sharedApplication()强制转换为AnyObject,然后创建一个等于方法签名的变量,将该变量设置为可选方法,然后测试该变量。这似乎没有用。我的猜测是,当针对iOS 8.0 SDK进行编译时,编译器知道它认为该方法应该在哪里,因此它将所有这些优化到内存查找。一切正常,直到我尝试测试该变量为止,此时我得到一个EXC_BAD_ACCESS。
但是,在同一个WWDC演讲中,我发现所有方法都是可选的,它们使用Optional Chaining来调用可选方法-这似乎可行。最me脚的是,您必须实际尝试调用该方法才能知道它是否存在,在注册通知的情况下,这是一个问题,因为您要在创建一个方法之前先弄清楚该方法是否存在。 UIUserNotificationSettings对象。似乎用nil调用该方法是可以的,所以似乎对我有用的解决方案是:
var ao: AnyObject = UIApplication.sharedApplication()
if let x:Void = ao.registerUserNotificationSettings?(nil) {
// It's iOS 8
var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
// It's older
var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}
经过大量与此相关的搜索后,关键信息来自此WWDC演讲https://developer.apple.com/videos/wwdc/2014/#407,位于中间的“协议中的可选方法”部分
在Xcode 6.1 beta中,上面的代码不再起作用,下面的代码起作用:
if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
// It's iOS 8
var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
// It's older
var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}