Overriding methods in Objective-C
I am relatively new to Objective-C, and I have been thinking about the fact that all methods are, in effect, virtual. I created this little console program:
#import <Foundation/Foundation.h>
@interface BaseClass : NSObject
{
}
- (void) virtualMethod: (NSInteger) integer;
@end
@interface DerivedClass : BaseClass
{
}
- (void) virtualMethod: (NSString *) string;
@end
@implementation BaseClass
- (void) virtualMethod: (NSInteger) integer
{
NSLog(@"%ld", integer);
}
@end
@implementation DerivedClass
- (void) virtualMethod: (NSString *)string
{
NSLog(@"%@", string); // Program received signal: "EXC_BAD_ACCESS". -- as expected
}
@end
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *arr = [NSArray arrayWithObjects: [BaseClass new], [DerivedClass new], nil];
for (int i = 0; i < arr.count; i++)
{
BaseClass *b = (BaseClass *)[arr objectAtIndex: i];
[b virtualMethod: i];
}
NSLog(@"\n\nTapos na!\n\n");
[pool drain];
return 0;
}
As expected, I got an EXC_BAD_ACCESS
in the derived virtualMethod:
, since after all, it doesn't take an integer, it takes an NSString *
as parameter. The virtual mechanism is based on selectors, and doesn't seem to take si开发者_如何学运维gnatures into account.
My question: is there something in the language that could prevent such an override with a different signature from happening? Some way to tell the compiler that virtualMethod:
should always have the same signature, or to make the compiler issue some kind of hint, warning or error if the signature doesn't match?
I know that a good programmer always indicates the names of types a method should have, but that is a convention, not a language rule. I am asking about a compiler feature to prevent the problem from happening.
Well, there is... but you probably don't want to use it. There's a build setting in Xcode called "Strict Selector Matching" (which passes through to the compiler as -Wstrict-selector-match
). This will warn you if the compiler finds two selectors that have different parameter or return types.
Unfortunately, the warning comes up even if the types are different, but compatible. As such, if you turn it on, you'll get a bunch of spurious warnings places that you wouldn't expect to be ambiguous. Feel free to try it out, though.
If you'd like to read more about it, Matt Gallagher wrote up a nice post about it. In the meantime, I'm afraid there's not a great solution here.
The current version of XCode gives you the following warning:
"Conflicting parameter types in implementation of '[method]': '[the type needed]' vs '[the type you wrongly chose]'"
精彩评论