Objective-C: 为什么不调用指定的初始化器?

Objective-C: Why not call the designated initializer?

我继承了这个代码:

- (id)initWithLocation:(CLLocation *)inLocation {
    if (self = [super init])
    {
        _location = [inLocation copy];
    }
    return self;
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init])
    {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

我想知道第一个方法不调用指定初始化程序(例如像这样 Is it okay to call an init method in self, in an init method?)是否有充分的理由?

即为什么不这样做:

- (id)initWithLocation:(CLLocation *)inLocation {
    if (self = [super init])
    {
        [self initWithLocation:inLocation offsetValue:nil];
    }
    return self;
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init])
    {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

更合适的方式是这样的:

- (id)initWithLocation:(CLLocation *)inLocation {
    return [self initWithLocation:inLocation offsetValue:nil];
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init]) {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

您真正需要做的是...

- (id)initWithLocation:(CLLocation *)inLocation {
    return [self initWithLocation:inLocation offsetValue:nil];
}

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset {
    if (self = [super init])
    {
        _location = [inLocation copy];
        _offset = [offset copy];
    }
    return self;
}

你是对的。在这种情况下没有理由不这样做。

- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset 方法应该是一个指定的初始化器,- (id)initWithLocation:(CLLocation *)inLocation 应该这样调用它:

- (id)initWithLocation:(CLLocation *)inLocation {
    return [self initWithLocation:inLocation offsetValue:nil];
}

使用 NS_DESIGNATED_INITIALIZER:

在 class 接口中标记指定的初始值设定项也被认为是一个好习惯
- (id)initWithLocation:(CLLocation *)inLocation offsetValue:(NSNumber *)offset NS_DESIGNATED_INITIALIZER;