开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜