哪些是用于汇总Objective-C初始化器的首选方法?

时间:2012-01-18 21:32:59

标签: objective-c initialization

给出以下初始化程序

- (id)initWithParameterA:(A *)a
{
    return [self initWithParameterA:a parameterB:nil parameterC:nil];
}

- (id)initWithParameterA:(A *)a parameterB:(B *)b
{
    return [self initWithParameterA:a parameterB:b parameterC:nil];
}

- (id)initWithParameterA:(A *)a parameterB:(B *)b parameterC:(C *)c
{
    // Actual initialization logic
}

以下哪两组便利初始化器更可取? (假设ARC。)

A组

+ (id)objectWithParameterA:(A *)a
{
    return [self objectWithParameterA:a parameterB:nil parameterC:nil];
}

+ (id)objectWithParameterA:(A *)a parameterB:(B *)b
{
    return [self objectWithParameterA:a parameterB:b parameterC:nil];
}

+ (id)objectWithParameterA:(A *)a parameterB:(B *)b parameterC:(C *)c
{
    return [[self alloc] initWithParameterA:a parameterB:b parameterC:c];
}

B组

+ (id)objectWithParameterA:(A *)a
{
    return [[self alloc] initWithParameterA:a parameterB:nil parameterC:nil];
}

+ (id)objectWithParameterA:(A *)a parameterB:(B *)b
{
    return [[self alloc] initWithParameterA:a parameterB:b parameterC:nil];
}

+ (id)objectWithParameterA:(A *)a parameterB:(B *)b parameterC:(C *)c
{
    return [[self alloc] initWithParameterA:a parameterB:b parameterC:c];
}

我理解 A组会导致额外的方法调用以获得实际的初始化逻辑的琐碎含义,但是对于这两种设计有什么更深刻的东西吗?

2 个答案:

答案 0 :(得分:2)

这个问题有点过于基于意见 - 所以你问的每个人都可能会有所不同。

你使用哪个小组是风格问题,虽然我会选择A组的DRY'er代码。我甚至可能会这样做

+ (id)objectWithParameterA:(A *)a
{
    return [self objectWithParameterA:a parameterB:nil];
}

+ (id)objectWithParameterA:(A *)a parameterB:(B *)b
{
    return [self objectWithParameterA:a parameterB:b parameterC:nil];
}

+ (id)objectWithParameterA:(A *)a parameterB:(B *)b parameterC:(C *)c
{
    return [[self alloc] initWithParameterA:a parameterB:b parameterC:c];
}

它添加了另一个方法调用,但我没有重复return [self objectWithParameterA:a parameterB:b parameterC:nil];这行两次。如果分析证明这是一个问题,我只会担心方法调用的性能损失。

那么我可能会给init方法提供相同的处理

- (id)initWithParameterA:(A *)a
{
    return [self initWithParameterA:a parameterB:nil];
}

- (id)initWithParameterA:(A *)a parameterB:(B *)b
{
    return [self initWithParameterA:a parameterB:b parameterC:nil];
}

- (id)initWithParameterA:(A *)a parameterB:(B *)b parameterC:(C *)c
{
    // Actual initialization logic
}

答案 1 :(得分:0)

要么有一个重要的警告:约定是object...应该返回一个未保留的对象,而new...应该返回一个保留的对象。因此,在ARC之前,您的object...方法会包含autorelease。现在,在ARC之后,你无法做到这一点,所以长期被忽视的new...模式已经被赋予了新的生命。

在@Rob评论之后澄清:ARC将为object...new...生成正确的代码 - 在前者中它将插入您以前必须手动执行的自动释放(它不需要更改后者的代码,因为alloc + init为您提供了一个保留对象)。考虑到这一点,我认为长期忽略的new...形式非常适合ARC代码 - 不需要进行自动释放比做一个更好。