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

rjs*_*ing 6 xcode gcc warnings pragma llvm

我想使用#pragma(在Xcode中)来抑制警告:

警告:找不到实例方法'-someMethod'(返回类型默认为'id')

我试过了:

#pragma GCC diagnostic ignored "-Wmissing-declarations"
Run Code Online (Sandbox Code Playgroud)

还有其他几个,但没有任何作用.

什么警告导致"找不到实例方法"?

编辑

这里要求的是实际代码:

...

if (sampleRate > 0 && ![self isFinishing])  //<--- Warning here
{
    return self.progress;
}

...
Run Code Online (Sandbox Code Playgroud)

和构建日志输出:

/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])
                            ^~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

rjs*_*ing 9

请参阅:https://stackoverflow.com/a/34043306/89035,以获取#pragma以禁止"找不到实例方法"警告.

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

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

  1. 选择目标
  2. 单击"Build Phases"选项卡
  3. 在"编译源"下,将-w开关添加到要禁止警告的文件

Xcode  - 编译源 - 抑制警告

  • 这不是一个真正的解决方案,忽略一个文件上的每个警告对于您的项目来说是一个非常糟糕的决定. (2认同)

Mec*_*cki 5

什么警告导致“找不到实例方法”?

那是-Wobjc-method-access,所以试试

#pragma GCC diagnostic ignored "-Wobjc-method-access"
Run Code Online (Sandbox Code Playgroud)

或编译该文件-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
Run Code Online (Sandbox Code Playgroud)

第一个 pragma 将所有当前警告标志保存到内部堆栈中,然后您将这个警告设置为忽略以供后续代码使用,在该代码之后,最后一行将弹出保存的状态,从而再次恢复所有警告标志。

请注意,您收到这样的警告这一事实意味着您的代码有些可疑。要么这个方法真的不存在,在那种情况下你真的不应该调用它,或者它会在运行时存在,你只是忘了告诉编译器。

首先你应该让你的代码安全,因为调用一个不存在的方法通常会使你的应用程序崩溃:

if (sampleRate > 0 
    && ([self respondsToSelector:@selector(isFinishing)] 
        && ![self isFinishing]
    )
) {
    return self.progress;
}
Run Code Online (Sandbox Code Playgroud)

此代码首先测试调用isFinishing是否正常或致命。只有在没有问题的情况下,才会实际执行调用。

现在编译器仍然需要知道这个方法isFinishing,不仅仅是它存在,还有它返回什么。![self isFinishing]对于返回布尔值、返回整数、返回双精度值或返回对象(或任何其他类型的指针)的方法,机器代码不一定相同。如果编译器知道该方法的原型,它只能生成正确的代码。最简单的方法是为此使用属性。如果您不想在头文件(.h 文件)中公开该属性,则可以在源文件(.m 文件)中声明该属性,只需在类扩展名中声明它(这基本上是一个未命名的类别):

@interface YourClass ( )
    @property (readonly) BOOL isFinishing;
@end

@implementation YourClass
// Implementation of the class follows here
Run Code Online (Sandbox Code Playgroud)

现在编译器知道isFinishing返回一个BOOL. 为了避免编译器为该属性生成任何代码,您将其放入实现中:

@dynamic isFinishing;
Run Code Online (Sandbox Code Playgroud)

这告诉编译器不要对该属性做任何事情(不要创建一个 ivar,不要创建一个 getter)并且只是假设在运行时一个名为的方法isFinishing将存在(编译器不会在运行时检查任何代码,它相信你的话!)