【问题标题】:Correct way to handle deprecated API处理已弃用 API 的正确方法
【发布时间】:2019-01-14 20:36:10
【问题描述】:

有一个 Obj-C 文件包含在具有不同部署目标的多个项目中。该文件有以下代码行:

[[UIApplication sharedApplication] openURL:url];

当我编译面向 iOS 10 的项目时,我收到警告:

'openURL:' 已弃用:在 iOS 10.0 中首次弃用 - 请改用 openURL:options:completionHandler:

我尝试使用以下结构来修复它:

if (@available(iOS 10.0, *)) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
    [[UIApplication sharedApplication] openURL:url];
}

但它仍然会产生相同的警告!

我不想在全局范围内关闭此警告,所以我结束的结果很可怕

if (@available(iOS 10.0, *)) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
    [[UIApplication sharedApplication] openURL:url];
    #pragma clang diagnostic pop
}

所以我想知道我是否真的需要这样一个丑陋的代码,或者我错过了什么,而这种情况可以用另一种(更优雅的)方式来处理?

【问题讨论】:

  • 虽然“警告”并不理想,但如果它仍然可以在那些较旧的目标设备上编译和工作,这真的很重要吗? iOS10+ 现在覆盖了约 99% 的 iPhone 安装和约 80% 的 iPad。除非您专门为继续支持旧 iPad 进行开发,否则几乎没有理由或好处费心解决这个问题。
  • 是的,您就是这样做的,但是您可以使用预处理器来减少样板。有关示例,请参见 stackoverflow.com/a/32515495/97337(特别是 NS_SUPPRESS_DIRECT_USE 宏)。如果您遇到很多这样的情况,我经常将这些内容归入-[UIApplication rn_openURL:] 之类的类别,这些类别对所有版本都“做正确的事”。
  • @RobNapier 但是有一些不涉及禁止警告的适当解决方案。
  • 弃用并不意味着禁止。您根本不需要禁止显示此消息。事实上,如果它在 iOS10 中被弃用,它很有可能在 iOS15 中仍然可用。
  • @GeneCode 正确,但大多数开发人员应该争取编译干净的代码。

标签: ios objective-c deprecated


【解决方案1】:

如果您的目标是 iOS 10 及更高版本,则无需支持已弃用的 API。就用新的吧。

不需要if/else。做吧:

[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];

就是这样。这个更新的 API 是在 iOS 10.0 中添加的。由于您仅支持 iOS 10 及更高版本,因此无需尝试使用已弃用的 API。

如果某些支持 iOS 10 及更高版本的项目以及某些需要支持比 iOS 10 更早版本的项目使用此代码,那么您需要以下内容:

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
    if (@available(iOS 10.0, *)) {
#endif
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
    } else {
        [[UIApplication sharedApplication] openURL:url];
    }
#endif

这个编译器指令的效果是,当在一个部署目标为 iOS 10.0 或更高版本的项目中构建时,编译后的代码简单地变成:

[[UIApplication sharedApplication] openURL:url options:@{} 

当代码构建在具有早于 iOS 10.0 的 Deployment Target 的项目中时,编译后的代码将是:

if (@available(iOS 10.0, *)) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
    [[UIApplication sharedApplication] openURL:url];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-12
    • 2014-04-14
    • 1970-01-01
    • 2015-07-16
    • 2019-07-12
    • 2011-12-24
    • 2020-02-26
    • 1970-01-01
    相关资源
    最近更新 更多