自定义初始化程序而不覆盖init?

时间:2014-01-29 10:23:30

标签: ios objective-c

您是否可以为类创建自定义初始化程序而不会覆盖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;
}

编辑:

从技术上讲,正确的方法是从init调用“指定初始化程序”,以涵盖将来可能只调用[[Class alloc] init]的可能性

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

3 个答案:

答案 0 :(得分:1)

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

请注意,您不需要实施该方法,因为它最多会调度super。如果您没有做任何自定义操作,请不要添加额外的代码。

答案 1 :(得分:1)

当然,如果我们假设您继承自NSObject,那么您可以这样做。 NSObject实现-(id)init,该方法继承到子类。

答案 2 :(得分:1)

Cocoa中的惯例是使用指定的初始化程序,这是所有其他初始化程序调用的初始化程序。它通常是具有最多参数的初始化程序(因为这些参数可以由其他初始化程序设置为默认值)

此外,此指定的初始化程序应将其超类的指定初始化程序称为其实现的一部分。

因此,在您的情况下,您已在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的情况下进行子类化。