I have a class whose methods are determined at runtime, as indicated in my question here. This works great, but now I have a bunch of warnings that look like the following littering my code:
Class method '+objectIsNotNil:' not found (return type defaults to 'id')
While these warnings don't actually affect the build process, they're very annoying and make it harder to spo开发者_如何学JAVAt relevant warnings. Is there some way to disable them, but only for the Assert
class (maybe some kind of macro)? If this isn't possible, then is there some way to turn them off for the entire build?
One alternative would be to use performSelector:withObject: instead of the direct method call. So instead of:
[Assert objectIsNotNil:object];
You could have:
[Assert performSelector:@selector(objectIsNotNil:) withObject:object];
It does not look quite as nice but it will remove the warnings. Furthermore, this pattern will work for any selector you want. To make things look a little better you could use macros in the following way:
#define ASSERT_PRECONDITION(sel, obj) [Assert performSelector:@selector(sel) withObject:obj]
This way your assert would look like this:
ASSERT_PRECONDITION(objectIsNotNil:, object);
these cases should be extremely rare...
I've declared a hidden protocol which declared the methods with proper signatures. 'Hidden' in the sense that it was only included by the translations which needed them.
@protocol MONRuntimeClassInterface
+ (BOOL)objectIsNotNil:(id)object;
@end
Easy answer:
You don't want to do this. And if I understand your problem right, you don't need to. You're defining all the relevant methods in your Predicate class described in the link and Assertion is just forwarding to them. Including Predicate.h and making sure everything's declared in the interface should work fine. Like methods called on objects typed id
, the compiler will consider methods called on a Class
object to be found so long as it knows of at least one class in that compilation unit that implements a class method with the same name.
Alternative answer:
If you really want to suppress compiler warnings, for example if you're calling a method that don't exist anywhere at compile-time then you need to use either NSObject's performSelector:
method or the runtime function objc_msgSend()
. This won't be checked for a matching method at compile time. However, for some C types which you could plausibly want to pass as arguments (floats and certain larger structs), the compiler needs to know their type. In the absence of a method definition, it needs information from you. performSelector:
works by only accepting objects of type id. objc_msgSend
needs casting casted to a function with the appropriate signature before it's called (and in some cases, replacing with a variant function). Mike Ash has a good explanation of how this works here.
精彩评论