Restrict method call to a specific class scope in Objective-C
The problem is that my "private" method (_init) is accidentally overridden by a subclass then never gets called any more:
@implementation Super
- (void)_ini开发者_如何学编程t {
}
- (id)init
{
[self _init];
return self;
}
@end
@implementation Sub
- (void)_init {
}
- (id)init
{
self = [super init];
if (self) {
[self _init];
}
return self;
}
@end
I realized this kind of problems can only be perfectly resolved if I can limit private method calls to current class scope (like the effect of scope resolution operator in C++). But is it possible in Objective-C?
Please be aware that telling me to change my private method names is not an anwser. The whole point of this problem is it is an accident — I could subclass other's class and accidentally stumble upon its private methods.
One solution is to avoid using []
to send the message, using IMP
instead:
- (id)init {
self = [super init];
if (! self) return nil;
// get the implementation pointer of -[Super _init]...
IMP superInit = class_getMethodImplementation([Super class], @selector(_init));
// ...and call it
superInit(self, @selector(_init));
return self;
}
Or, if you don’t want subclasses to see that method at all, make it a file scope function instead:
static void customInit(Super *self) {
}
- (id)init {
self = [super init];
if (self) customInit(self);
return self;
}
Bear in mind that if you’re developing on Apple platforms then you shouldn’t use an underscore as a prefix to indicate that a method is private: Apple reserves this convention. Otherwise, you could be inadvertently overriding an Apple private method.
精彩评论