I have the following classes/protocols:
@interface Super
@end
@implementation Super
@end
@interface Sub1
@end
@implementation Sub1
@end
@interface Sub2
@end
@implementation Sub2
@end
@protocol FooProtocol
- (void) foo;
@end
@interface Sub1 (FooCategory) <FooProtocol>
@end
@implementation Sub1 (FooCategory)
- (void) foo {}
@end
@interface Sub2 (FooCategory) <FooProtocol>
@end
@implementation Sub2 (FooCategory)
- (void) foo {}
@end
@interface Super (FooCategory) <FooProtocol>
@end
// Notice that there is no @implementation Super (FooCategory)
This allows me to write a function similar to this:
void callFoo(NSArray *supers) {
for (Super *theSuper in supers) {
[theSuper foo];
}
}
Sub1 and Sub2 are Super‘s only two subclasses. I essentially want polymorphism in a category method. If I specify an @interface for Super, but provide no @implementation, clang doesn’t give me any warnings/errors.
Is this a really bad hack?
What are the potential downsides?
(Originally from a comment on zneak’s answer.)
As explained in The Objective-C Programming Language, a method in a category truly becomes part of the targeted class at runtime – which is why it can be dangerous to clobber an existing method, and why the behavior of multiple categories implementing the same method is undefined. Once the method is installed, it’s really no different from something that was there initially:
It’s okay to have a category on
Superand categories on its subclasses implementing the same method, and it’ll work exactly like if they were part of the classes themselves. (Though I do recommend following zneak’s advice of implementing a stub method onSuperto help with debugging if it ever gets invoked accidentally.)