Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using #pragma to suppress “Instance method not found” warnings in Xcode

I want to use #pragma (in Xcode) to suppress the warning:

warning: instance method '-someMethod' not found (return type defaults to '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])
                            ^~~~~~~~~~~~~~~~~~
like image 524
Richard Stelling Avatar asked Feb 16 '12 11:02

Richard Stelling


People also ask

What is the synonym of using?

Synonym Chooser The words employ and utilize are common synonyms of use. While all three words mean "to put into service especially to attain an end," use implies availing oneself of something as a means or instrument to an end.

What type of word is using?

Using is a verb - Word Type.

What is the meaning of using someone?

transitive verb. If you say that someone uses people, you disapprove of them because they make others do things for them in order to benefit or gain some advantage from it, and not because they care about the other people. [disapproval]


2 Answers

See: https://stackoverflow.com/a/34043306/89035 for a #pragma to suppress "instance method not found" warnings.

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.

NB: This solution is for Xcode 4.2 and above

  1. Select the target
  2. Click on the "Build Phases" tab
  3. Under "Compile Sources" add the -w switch to the file(s) you wish to suppress warnings on

Xcode - compile sources - suppress warnings

like image 157
Richard Stelling Avatar answered Sep 26 '22 08:09

Richard Stelling


What warning causes the "instance method not found"?

That's -Wobjc-method-access, so try

#pragma GCC diagnostic ignored "-Wobjc-method-access"

or compile that file with -Wno-objc-method-access to only suppress that warning.

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:

#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.

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):

@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:

@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!)

like image 29
Mecki Avatar answered Sep 22 '22 08:09

Mecki