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])
^~~~~~~~~~~~~~~~~~
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
- 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
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!)
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 uses the method, thus:
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
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.
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.
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
来源:https://stackoverflow.com/questions/9310141/using-pragma-to-suppress-instance-method-not-found-warnings-in-xcode