如何同时支持 iOS 7 和 8 的 NSCalendar?

16

iOS 8为旧方法引入了一些新的值。 例如,创建一个日历以前是这样的:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

现在,日历标识符已更改,我应该这样创建对象:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

问题在于,编译器只在第一种情况下警告我 NSGregorianCalendar 已被弃用。然而,编译器根本不提醒我关于 NSCalendarIdentifierGregorian 在 iOS 7 下的兼容性。
这是否意味着 NSCalendarIdentifierGregorian 在 iOS 7 上也能工作?
如果不能,那么根据操作系统版本创建具有日历标识符的最佳方法是什么?每次检查操作系统版本似乎很繁琐。

谢谢。


5
如果你的 iOS 部署目标是 iOS 7,那么请使用 NSGregorianCalendar。它可以在 iOS 7 和 iOS 8 下正常工作,并且不会收到任何弃用警告。 - rmaddy
1
@rmaddy为什么不把你的评论放在答案里呢? - LolaRun
2个回答

31
你可以使用内置的__IPHONE_8_0宏,结合自定义宏。
你的自定义宏将简单地引用在Objective-C中定义的底层值。由于这些是广泛使用的方便定义,我将它们放入头文件中,并将其包含到我的PCH文件中(在Xcode 6中,您必须自己创建预编译器头文件,并在构建设置中指向它)。
当iOS 9发布时,即使不更新,您仍然可以使用__IPHONE_8_0,因为它仍将被定义为iOS 8之后的所有版本。
在头文件中(或预编译器头文件-project_name.pch)。
#ifdef __IPHONE_8_0
    #define GregorianCalendar NSCalendarIdentifierGregorian
#else
    #define GregorianCalendar NSGregorianCalendar
#endif

在您的实现文件中

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:GregorianCalendar];

NSCalendarIdentifierGregorian NS_AVAILABLE(10_6, 4_0)。 为什么你不在这两种情况下都使用这个const? - Valentin Shamardin
1
在使用xCode 5编译iOS 7.1时,使用NSCalendarIdentifierGregorian会导致编译器错误:'NSCalendarIdentifierGregorian' is unavailable: not available on iOS。通过我的答案中的定义,GregorianCalendar在xCode 5和6上都等同于'gregorian'。我认为这在与一些仍在使用xCode 5进行开发的开发人员合作时非常有用。 - Sheamus
未来版本的SDK是否有保证const仍将解析为“Gregorian”? - Gabriel
回答你的问题,@Gabriel,目前看来这些常量不太可能很快被重命名。但是,即使它们被重命名了,__IPHONE_8_0仍将被定义,因为在iOS 8期间和之后的所有版本中都保证会定义它。 - Sheamus

2

我知道你具体问的是公历,但无论如何使用以下方式是否总是更好:

NSCalendar *calendar = [NSCalendar currentCalendar];

وœ‰و—¶و‚¨ه؟…é،»ن»…ن½؟用NSGregorianCalendar,ن¾‹ه¦‚هœ¨ن¸؛EKReminder设置startDateComponentsه’ŒdueDateComponentsو—¶م€‚ - Lion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接