自定义初始评估器而无需覆盖初始化



您可以为类创建一个无需过度载入init的类的自定义初始分散器吗?

例如,您可以这样做:

+ (instancetype)node {
    BetterSKNode *newNode = [[BetterSKNode alloc]initWithRootName:@"ROOT"];
    return newNode;
}
- (id)initWithRootName:(NSString *)rootName {
    self = [super init];
    if(self) {
        _rootName = rootName;
    }
    return self;
}

如果您这样做应该是self = [super init];self = [self init];

它很容易添加(请参见下文),但是我很好奇是否需要?

- (id)init  {
    self = [super init];
    if(self) {
        // ...
    }
    return self;
}

编辑:

从技术上讲,正确的方法是将"指定的初始评估器"称为启动,以涵盖某人将来可能只致电[[class alloc] init]

- (id)init {
    self = [self initWithRootName:@"ROOT"];
    return self;
}

可可中的约定是具有指定的启动器,这是所有其他初始评估者所调用的初始分散器。它通常是具有最多参数的初始评估器(因为可以设置为其他初始评估器将其设置为默认值)

此外,该指定的初始评估者应将其指定的初始评估器称为其实现的一部分。

因此,在您的情况下,您已经在 initWithRootName:中有一个指定的初始分散器,因此您的代码看起来像:

+ (instancetype)node {
    BetterSKNode *newNode = [[BetterSKNode alloc]initWithRootName:@"ROOT"];
    return newNode;
}
- (id)initWithRootName:(NSString *)rootName {
    self = [super init]; // Assuming that init is the designated initialiser of the superclass
    if(self) {
        _rootName = rootName;
    }
    return self;
}
// If you choose to add an init, method then it should call the designated initialiser
- (id)init {
    return [self initWithRootName:@"ROOT"]; // use a default value for the parameter
}

是的,您可以在不覆盖init的情况下子类。

使用 self = [self init];可以保护您免受将来的更改,在该更改中,您可以将init方法添加到同类中,但是您可以在将来重构时添加它。

请注意,您不需要实现该方法,因为它将分配到super。如果您不做任何自定义的事情,请不要添加额外的代码。

当然,如果我们假设您是从NSObject继承的,则可以做到。NSObject实现-(id)init,该方法继承为子类。

最新更新