5

我试图通过定义一个-(id)init名为init.initWithFrameinitWithCodercommonConstruct

此方法执行所有 init 方法风格共有的繁重工作,并由init构造函数调用。

我现在遇到的问题是,在派生类中,对初始化程序助手(“commonConstruct”)使用相同的命名对流,基类将调用派生类commonConstruct,尽管它是invisible,即在.m文件中声明,而不是在.h文件中。

但是,运行时会找到重载的 commonConstruct 并执行它而不是它自己的成员函数。

除了在每个子类中为初始化程序助手使用不同的名称之外,还有其他方法吗?

换句话说:有没有办法制作Objective-C“非虚拟”的成员函数,即没有后期(运行时)但编译时绑定?

4

2 回答 2

4

没有好的编译器强制方法可以做到这一点。方法始终是“虚拟的”,并且没有强制执行“私有”方法。

常见的解决方案是将类名嵌入方法名中,因此:

@implementation Thing

- (instancetype)init {
    if (self = [super init]) {
        [self Thing_commonInit];
    }
    return self;
}

- (instancetype)initWithArg:(NSObject *)arg {
    if (self = [super init]) {
        [self Thing_commonInit];
        [self doSomethingWithArg:arg];
    }
    return self;
}

- (void)Thing_commonInit {
    ...
}
于 2013-06-20T08:54:05.403 回答
3

除了 Rob Mayoff 的解决方案(我也使用它)之外,您还可以使用静态 C 函数:

@implementation Thing
{
    id _privateIvar;
}

- (id)init
{
    return commonInit([super init], nil);
}

- (id)initWithArgument:(id)argument
{
    return commonInit([super init], argument);
}

static Thing *commonInit(Thing *self, id argument)
{
    if (self == nil)
        return nil;
    self->_privateIvar = argument;
    return self;
}

@end

静态函数不发出符号,因此没有可能的冲突。您可以命名所有常见的初始化程序commonInit

于 2013-06-20T09:22:11.493 回答