I'm writing a library, which will potentially be used by people that aren't me.
Let's say I write a class:
InterestingClass.h
@interface InterestingClass: NSObject
- (id)initWithIdentifier:(NSString *)Identifier;
@end
InterestingClass.m
@interface InterestingClass()
- (void)interestingMethod;
@end
@implementation InterestingClass
- (id)initWithIdentifier:(NSString *)Identifier {
self = [super init];
if (self) {
[self interestingMethod];
}
return self;
}
- (void)interestingMethod {
//do some interesting stuff
}
@end
What if somebody is using the library later down the line and decides to create a subclass of InterestingClass
?:
InterestingSubClass.h
@interface InterestingSubClass: InterestingClass
@end
InterestingSubClass.m
@interface InterestingSubClass()
- (void)interestingMethod;
@end
@implementation InterestingSubClass
- (void)interestingMethod {
//do some equally interesting, but completely unrelated stuff
}
@end
The future library user can see from the public interface that initWithIdentifier
is a method of the superclass. If they override this method, they'll probably assume (correctly) that the superclass
method should be called in the subclass implementation.
However, what if they define a method (in the subclass private interface) which inadvertently has the same name as an unrelated method in the superclass 'private' interface? Without them reading the superclass private interface, they won't know that instead of just creating a new method, they've also overridden something in the superclass. The subclass implementation may end up getting called unexpectedly, and the work that the superclass is expecting to be done when calling the method will not get done.
All of the SO questions I've read seem to suggest that this is just the way that ObjC works and that there isn't a way of getting around it. Is this the case, or can I do something to protect my 'private' methods from being overridden?
Alternatively, is there any way to scope the calling of methods from my superclass so I can be sure that the superclass implementation will be called instead of a subclass implementation?
AFAIK, the best you can hope for is declaring that overrides must call super. You can do that by defining the method in the superclass as:
- (void)interestingMethod NS_REQUIRES_SUPER;
This will compile-time flag any overrides that don't call super.
For framework code a simple way to deal with this is to just give all of your private methods a private prefix.
You'll often notice in stack traces that the Apple frameworks call private methods often starting with an under bar _
.
This would only really be a real concern if you are indeed providing a framework for external use where people can not see your source.
NB
Don't start your methods with an under bar prefix as this convention is already reserved
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With