我想使用#pragma
(在Xcode中)来禁止警告:
警告:找不到实例方法'-someMethod'(返回类型默认为'id')
我试过了:
#pragma GCC diagnostic ignored "-Wmissing-declarations"
还有其他几个,但没有任何作用。
什么警告导致“找不到实例方法”?
这里要求的是实际代码:
...
if (sampleRate > 0 && ![self isFinishing]) //<--- Warning here
{
return self.progress;
}
...
构建日志输出:
/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])
^~~~~~~~~~~~~~~~~~
答案 0 :(得分:9)
请参阅:https://stackoverflow.com/a/34043306/89035了解#pragma以禁止&#34;找不到实例方法&#34;警告。
虽然看起来不存在真正的#pragma
解决方案,但可以通过使用-w
开关来关闭单个文件中的警告。
注意: 此解决方案适用于Xcode 4.2及更高版本
-w
开关添加到您希望在
答案 1 :(得分:4)
什么警告导致找不到&#34;实例方法&#34;?
那是-Wobjc-method-access
,所以请尝试
#pragma GCC diagnostic ignored "-Wobjc-method-access"
或使用-Wno-objc-method-access
编译该文件以仅取消该警告。
上述两种解决方案都有限制,它们将应用于整个文件,这通常不是您想要的。 clang
为您提供了更好的选择:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
if (sampleRate > 0 && ![self isFinishing])
{
return self.progress;
}
#pragma clang diagnostic pop
第一个pragma将所有当前警告标志保存到内部堆栈,然后将此一个警告设置为忽略代码,并且在该代码之后,最后一行将弹出保存状态,从而再次恢复所有警告标志
请注意,您收到此类警告的事实意味着您的代码很可疑。这个方法真的不存在,在这种情况下你真的不应该调用它,或者它会在运行时存在,你只是忘了告诉编译器。
首先,您应该使代码安全,因为调用不存在的方法通常会使app崩溃:
if (sampleRate > 0
&& ([self respondsToSelector:@selector(isFinishing)]
&& ![self isFinishing]
)
) {
return self.progress;
}
此代码首先测试调用isFinishing
是否正常或相当致命。只有在没有问题的情况下才能实际进行通话。
现在编译器仍然需要知道方法isFinishing
,不仅仅是它存在而且还有它返回的内容。对于返回bool,返回整数,返回double或返回对象(或任何其他类型的指针)的方法,![self isFinishing]
的机器代码不一定相同。如果编译器知道该方法的原型,则只能生成正确的代码。最简单的方法是使用属性。您可以在源文件(.m文件)中声明该属性,如果您不想在头文件(.h文件)中公开它,只需在类扩展中声明它(即`基本上是一个未命名的类别):
@interface YourClass ( )
@property (readonly) BOOL isFinishing;
@end
@implementation YourClass
// Implementation of the class follows here
现在编译器知道isFinishing
返回BOOL
。为避免编译器为该属性生成任何代码,请将其放入实现中:
@dynamic isFinishing;
这告诉编译器不要为该属性做任何事情(不要创建一个ivar,不要创建一个getter),只是假设在运行时会存在一个名为isFinishing
的方法(编译器不会在运行时进行任何代码检查,它会信任你的话!)
答案 2 :(得分:3)
好的,我再次:)我尝试了各种'clang'特定的#pragma
但没有任何效果,我唯一能想到的就是将该方法声明为实际类中的“私有方法” 使用方法,因此:
的main.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:
#import <Foundation/Foundation.h>
@interface PragmaTest : NSObject
@end
PragmaTest.m:
#import "PragmaTest.h"
@implementation PragmaTest
- (void)noSuchMethod
{
NSLog(@"noSuchMethod");
}
@end
我希望这符合您的要求,虽然这不是涉及#pragma
的解决方案,但我希望您不会觉得有必要给出有用的答案。
答案 3 :(得分:1)
Pavan的链接很好,但也可能有一个更明显的答案。你的.m文件中的isFinishing方法是否在使用后声明(在你收到警告的地方)?如果是这样,请在使用之前移动声明。 如果这个简单的情况不是您可能想要的答案,您可以使用类别让编译器了解此方法。我经常这样做单元测试“私人”方法。 另一种选择是使用此文件的编译器标志来抑制整个文件的此警告。 我知道这些都没有说明如何用pragma解决这个问题,但你可能会发现另一种解决方案可行。
答案 4 :(得分:1)
这是您可以抑制警告的方法。这在测试(假)类中特别有用,在这些类中,您只想实现一些类的几种方法而不需要其余的方法。
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
@implementation MyClass
@end
#pragma clang diagnostic pop