使用#pragma在Xcode中禁止“找不到实例方法”警告

时间:2012-02-16 11:04:03

标签: xcode gcc warnings llvm pragma

我想使用#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])
                            ^~~~~~~~~~~~~~~~~~

5 个答案:

答案 0 :(得分:9)

  

请参阅:https://stackoverflow.com/a/34043306/89035了解#pragma以禁止&#34;找不到实例方法&#34;警告。

虽然看起来不存在真正的#pragma解决方案,但可以通过使用-w开关来关闭单个文件中的警告。

注意: 此解决方案适用于Xcode 4.2及更高版本

  1. 选择目标
  2. 点击&#34;构建阶段&#34;标签
  3. 根据&#34;编译来源&#34;将-w开关添加到您希望在
  4. 上禁止警告的文件中

    Xcode - compile sources - suppress warnings

答案 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