在Xcode中禁用已弃用的警告

145

随着各种SDK的出现,能够为多个SDK和平台构建应用程序非常方便。然而,从3.2到3.0甚至偶尔到2.x的跳转中,我经常会收到有关已更改或被取代的方法的弃用警告:

warning: 'UIKeyboardBoundsUserInfoKey' is deprecated.

由于我仍然希望与旧操作系统保持兼容性,并且在构建时也在努力消除“噪音”,是否有一种方法可以关闭或禁用这些警告?


4
保罗R的回答是有效的,但请考虑manicaesar更为精准,它可以让你抑制你想要的警告,而不会失去其他可能很重要的附加警告。在最佳实践方面,我认为manicaesar给出了正确的答案™。 - Olie
对于这个问题在 Swift 中的等价方法是:如何在 Swift 中消除警告? - Cœur
10个回答

347

由于我还不能在@samiq的帖子下添加评论,所以我想我会扩展它。在使用弃用内容的函数/方法之前提到输入指令。然后在函数结尾的定义后可以恢复先前的设置:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma GCC diagnostic pop

1
太棒了的提示!可惜它不能在方法内声明。 - Dustin
13
实际上可以在方法内声明。今天我不得不这样做是因为文档/SDK中存在一个错误。 - jer
7
一个稍微更好的方法是使用以下语法:#pragma GCC diagnostics push #pragma GCC diagnostics ignored "-Wdeprecated-declarations" .. .. 在这里写代码 .. .. #pragma GCC diagnostic pop这种方法会将你恢复到之前的设置状态。更多信息请参考:[http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html] - Niclas
4
根据建议进行了更改 :) - manicaesar
这在 Swift 中的等效物是什么? - Hogdotmac
@Hogdotmac 上次我查看(Swift 4.1 :P),在Swift中没有类似的东西。 - manicaesar

153

Clang提供了一个不错的特性,使得@manicaesar帖子中的“还原”步骤与初始警告状态无关:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

引用Clang的手册

除了GCC的#pragma提供的所有功能外,Clang还允许您推入和弹出当前警告状态。这在编写将由他人编译的头文件时特别有用,因为您不知道他们使用哪些警告标志。


1
较新版本的GCC使用相同的语法(将clang替换为GCC)。 - Niclas
3
我经常对LLVM、GCC和Clang的概念感到困惑,所以我写下这个笔记来节省时间。GNU编译器套件(GCC)曾与Xcode 3一起使用,然后苹果发布了带有混合LLVM-GCC的Xcode 4。现在,低级虚拟机(LLVM)编译器已经接管了,更多信息请参见http://llvm.org。从Xcode 7.2.1开始,默认编译器是Apple LLVM 7.0。LLVM编译器是其他“项目”(调试器和其他工具)的库,其中包括Clang本地编译器。Clang是一个“LLVM本地”的C/C++/Objective-C编译器。 - serge-k

86

尝试使用-Wno-deprecated-declarations或在Xcode中找到对应的设置GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS(专业提示:只需在构建设置中键入“已弃用”即可找到此警告的特定设置)。

当前版本的Xcode(例如Xcode 9.2):

enter image description here


早期版本的Xcode(例如Xcode 2.x、3.x):

enter image description here


17
原文:Turns out it's even easier than that; there's a checkbox in the Xcode target settings; your answer prompted me to search there. Thanks! 翻译:事实证明这比那更容易,Xcode目标设置中有一个复选框;你的回答促使我在那里搜索。谢谢! - Ben Gottlieb
4
您还可以按文件单独执行此操作。有关添加每个文件标志的方法,请参见此答案:https://dev59.com/T2w15IYBdhLWcg3wYawx#6658549 - mrwalker
5
像这样的回答对于新手来说是令人沮丧的。 "Try it where?" 是指在哪里尝试?"How do I find target settings?" 是指如何找到目标设置?稍微加些解释会增加此答案的价值。 - noogrub
10
这个解释如此不清楚,不应被标记为正确的答案。 - Chris Hatton
6
在构建设置中搜索“已弃用”,你会看到它。 - quantumpotato
显示剩余2条评论

49

由于我们通常需要支持旧的操作系统,但要注意我们的警告信息,因此我希望有一种更加整洁的方式来完成这个任务。我受到Mozilla一些代码的启发,写了以下内容:

#define SILENCE_DEPRECATION(expr)                                   \
do {                                                                \
_Pragma("clang diagnostic push")                                    \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")   \
expr;                                                               \
_Pragma("clang diagnostic pop")                                     \
} while(0)

#define SILENCE_IOS7_DEPRECATION(expr) SILENCE_DEPRECATION(expr)
#define SILENCE_IOS8_DEPRECATION(expr) SILENCE_DEPRECATION(expr)

这使您能够执行以下操作:

SILENCE_IOS7_DEPRECATION(return [self sizeWithFont:font constrainedToSize:size]);

它也适用于代码块:

SILENCE_IOS7_DEPRECATION(
    view = [[MKPolylineView alloc] initWithPolyline:self];
    view.lineWidth = self.lineWidth;
    view.strokeColor = self.color;
);

而且,当您停止支持iOS 7之前的设备时,您可以轻松搜索代码以查找需要修复的已弃用用法。


这是一种非常优美的解决常见问题的方式。我很感激你的努力。 - Scott D
1
为什么需要使用 do {...} while(0) - Ky -
1
@BenC.R.Leggiero 因为你没有传递一个块,而是在括号之间放置了多个语句。你基本上是为每一行抑制警告。 - Alejandro Iván
1
@AlejandroIván 我知道你的解释对你来说很有意义...但对我来说,它看起来只是在重新表述问题。你能解释一下为什么在这里特别需要 do{...}while(0); 吗?为什么不只用 {...}?为什么不用 if(true){...} 等等。 - Ky -
2
@BenC.R.Leggiero 你是对的。由于某种原因,我误读了你的问题。请查看这里的被接受的答案:https://dev59.com/qXVC5IYBdhLWcg3w4Vb6#154138 - Alejandro Iván
显示剩余4条评论

29
你也可以通过使用 来对每个文件抑制警告。
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

这反过来比仅仅一次抑制所有警告更好的实践方式稍微好一些......毕竟你得知道自己在做什么。


27

如果您想消除警告实现弃用的方法 实现弃用的类,请使用以下代码:

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-implementations"
    // 代码
    #pragma clang diagnostic pop


1
当我看到“-Wdeprecated-declarations”时,我猜想一定会有“-Wdeprecated-implementations”。而且它真的有效。谢谢。 - DawnSong
“-Wdeprecated-declarations” 对我没用。而“-Wdeprecated-implementations” 是有效的。谢谢。 - m8labs

9

在您的构建设置中,找到已弃用的函数

enter image description here


它将关闭所有“已弃用”的警告,但只有一些警告需要被抑制。 - DawnSong

7

如果您想对一段代码进行所有种类的过时检查,请使用以下命令:-Wdeprecated

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
- (void) methodUsingDeprecatedStuff {
    //use deprecated stuff
}
#pragma clang diagnostic pop

0
在问题导航器中添加过滤器。

enter image description here


-3

要禁用第三方头文件的警告,请在文件顶部添加以下行:

#pragma clang system_header

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