使用 #pragma 抑制 Xcode 中的“未找到实例方法”警告
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9310141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using #pragma to suppress “Instance method not found” warnings in Xcode
提问by Richard Stelling
I want to use #pragma
(in Xcode) to suppress the warning:
我想使用#pragma
(在 Xcode 中)来抑制警告:
warning: instance method '-someMethod' not found (return type defaults to 'id')
警告:未找到实例方法“-someMethod”(返回类型默认为“id”)
I've tried:
我试过了:
#pragma GCC diagnostic ignored "-Wmissing-declarations"
And several others, but nothing works.
还有其他几个,但没有任何效果。
What warning causes the "instance method not found"?
什么警告导致“找不到实例方法”?
Edit
编辑
As requested here is the actual code:
根据这里的要求是实际代码:
...
if (sampleRate > 0 && ![self isFinishing]) //<--- Warning here
{
return self.progress;
}
...
And the build log output:
和构建日志输出:
/Users/User1/Documents/Project/branch/client/Folder/CodeFile.m:26:32:{26:32-26:50}: warning: instance method '-isFinishing' not found (return type defaults to 'id') [3]
if (sampleRate > 0 && ![self isFinishing])
^~~~~~~~~~~~~~~~~~
回答by Richard Stelling
See: https://stackoverflow.com/a/34043306/89035for a #pragma to suppress "instance method not found" warnings.
请参阅:https://stackoverflow.com/a/34043306/89035 以了解 #pragma 以抑制“未找到实例方法”警告。
While it seem that a true #pragma
solution to this does not exist turning off the warnings in individual files can be accomplished by use of the -w
switch.
虽然似乎#pragma
不存在真正的解决方案,但可以通过使用-w
开关来关闭单个文件中的警告。
NB:This solution is for Xcode 4.2 and above
注意:此解决方案适用于 Xcode 4.2 及更高版本
- Select the target
- Click on the "Build Phases" tab
- Under "Compile Sources" add the
-w
switch to the file(s) you wish to suppress warnings on
- 选择目标
- 单击“构建阶段”选项卡
- 在“编译源”下,将
-w
开关添加到您希望抑制警告的文件中
回答by Mecki
What warning causes the "instance method not found"?
什么警告导致“找不到实例方法”?
That's -Wobjc-method-access
, so try
那是-Wobjc-method-access
,所以试试
#pragma GCC diagnostic ignored "-Wobjc-method-access"
or compile that file with -Wno-objc-method-access
to only suppress that warning.
或编译该文件-Wno-objc-method-access
以仅抑制该警告。
Both solutions above have the limitation that they will apply to the whole file, which is usually not what you want. clang
offers you an even better alternative:
上述两种解决方案都有一个限制,即它们将应用于整个文件,这通常不是您想要的。clang
为您提供更好的选择:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
if (sampleRate > 0 && ![self isFinishing])
{
return self.progress;
}
#pragma clang diagnostic pop
The first pragma saves all current warning flags to an internal stack, then you set this one warning to ignored for the code to follow and after that code, the last line will pops the saved state and thus restore all the warnings flags again.
第一个编译指示将所有当前警告标志保存到一个内部堆栈中,然后您将这个警告设置为忽略以供后续代码使用,在该代码之后,最后一行将弹出保存的状态,从而再次恢复所有警告标志。
Note that the fact that you get such a warning at all means something is fishy about your code. Either this method really doesn't exist, in that case you really shouldn't call it, or it will exist at runtime, you just forgot to tell the compiler about that.
请注意,您收到这样的警告这一事实意味着您的代码有些可疑。要么这个方法真的不存在,在那种情况下你真的不应该调用它,或者它会在运行时存在,你只是忘了告诉编译器。
First you should make your code safe because calling a non-existing method will usually crash you app:
首先,您应该使您的代码安全,因为调用不存在的方法通常会使您的应用程序崩溃:
if (sampleRate > 0
&& ([self respondsToSelector:@selector(isFinishing)]
&& ![self isFinishing]
)
) {
return self.progress;
}
This code first tests if calling isFinishing
is okay or rather fatal. Only if it is okay the call is actually performed.
此代码首先测试调用isFinishing
是否正常或致命。只有在没有问题的情况下,才会实际执行调用。
Now the compiler still needs to know about the method isFinishing
, not just that it exists but also what it returns. The machine code for ![self isFinishing]
is not necessarily the same for a method returning a bool, returning an integer, returning a double or returning an object (or any other kind of pointer). The compiler can only generate correct code if it knows the prototype of that method. The easiest way is to use a property for that. You can declare that property in your source file (the .m file) if you don't want to expose it in your header file (the .h file), just declare it in a class extension (that's basically an unnamed category):
现在编译器仍然需要知道这个方法isFinishing
,不仅仅是它存在,还有它返回什么。![self isFinishing]
对于返回布尔值、返回整数、返回双精度值或返回对象(或任何其他类型的指针)的方法,机器代码不一定相同。如果编译器知道该方法的原型,它只能生成正确的代码。最简单的方法是为此使用属性。如果您不想在头文件(.h 文件)中公开该属性,则可以在源文件(.m 文件)中声明该属性,只需在类扩展中声明它(这基本上是一个未命名的类别):
@interface YourClass ( )
@property (readonly) BOOL isFinishing;
@end
@implementation YourClass
// Implementation of the class follows here
Now the compiler knows that isFinishing
returns a BOOL
. And to avoid that the compiler generates any code for that property, you put that into the implementation:
现在编译器知道isFinishing
返回一个BOOL
. 为了避免编译器为该属性生成任何代码,您将其放入实现中:
@dynamic isFinishing;
This tells the compiler to not do anything for that property (don't create an ivar, don't create a getter) and just assume that at runtime a method named isFinishing
will exist (the compiler will not make any code to check at runtime, it trusts your word!)
这告诉编译器不要对该属性做任何事情(不要创建一个 ivar,不要创建一个 getter)并且只是假设在运行时一个名为的方法isFinishing
将存在(编译器不会在运行时检查任何代码,它相信你的话!)
回答by trojanfoe
OK, me again :) I tried various 'clang' specific #pragma
s but nothing worked, and only thing I could think of was to declare the method as a 'private method' from within the class that actually usesthe method, thus:
好的,我又来了 :) 我尝试了各种特定于 'clang' 的#pragma
s 但没有任何效果,我唯一能想到的就是从实际使用该方法的类中将该方法声明为“私有方法” ,因此:
main.m:
主.m:
#import <Foundation/Foundation.h>
#import "PragmaTest.h"
@interface PragmaTest ()
- (void)noSuchMethod;
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
PragmaTest *pragmaTest = [[PragmaTest alloc] init];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wall"
[pragmaTest noSuchMethod];
#pragma clang diagnostic pop
[pragmaTest release];
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
PragmaTest.h:
PragmaTest.h:
#import <Foundation/Foundation.h>
@interface PragmaTest : NSObject
@end
PragmaTest.m:
PragmaTest.m:
#import "PragmaTest.h"
@implementation PragmaTest
- (void)noSuchMethod
{
NSLog(@"noSuchMethod");
}
@end
I hope this meets your requirements and although it's not a solution involving #pragma
s I hope you won't feel the need to downvote a helpful answer.
我希望这满足您的要求,虽然它不是一个涉及#pragma
s的解决方案,但我希望您不会觉得有必要对一个有用的答案投反对票。
回答by mahboudz
This is how you can suppress the warnings. This is especially useful in test (fake) classes where you want to implement only a few methods of a class and don't need the rest.
这就是您可以抑制警告的方法。这在测试(假)类中特别有用,在这些类中您只想实现一个类的几个方法而不需要其余的方法。
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
@implementation MyClass
@end
#pragma clang diagnostic pop
回答by rooftop
Pavan's link is good but there might also be a simple more obvious answer. Is your isFinishing method in your .m file but declared after its usage (where you get the warning)? If so, move the declaration before its usage. If that simple case is not the answer you might want you can use a category to let the compiler know about this method. I frequently do this to unit test "private" methods. Another option is to use a compiler flag for this file to suppress this warning for the entire file. I know none of those specify how to solve this with a pragma but you might find another solution viable.
Pavan 的链接很好,但也可能有一个更简单的答案。您的 isFinishing 方法是否在 .m 文件中,但在使用后声明(在那里收到警告)?如果是这样,请在使用之前移动声明。如果这个简单的情况不是您可能想要的答案,您可以使用一个类别让编译器知道此方法。我经常这样做来对“私有”方法进行单元测试。另一种选择是为此文件使用编译器标志来抑制整个文件的此警告。我知道这些都没有指定如何使用编译指示解决这个问题,但您可能会发现另一种可行的解决方案。