5

我对 Objective-C 很陌生,我有一个问题。

我创建了一个自定义类并尝试为初始化创建重载:

- (id)init
{
    if (self = [super init]) {
        [self setIsCurrentCar:NO];
    }
    return self;
}

-(id) initWithID:(NSInteger)id {
    if(self = [self init]) {
        [self setID:id];
    }
    return self;
}

-(id) initWithID:(NSInteger)id CarYear:(NSString *)year {
    if(self = [self initWithID:id]) {
        [self setCarYear:year];
    }
    return self;
}

假设在某一时刻,我调用了该-(id) initWithIDCarYear方法。

我想知道上面的代码在结构上是正确的。

  • 在此代码中,self设置为 3 次。有更好的解决方案吗?
  • 我在这段代码中有内存泄漏吗?(使用 ARC)
  • 我必须if(self = ...)始终检查还是它是冗余代码?

谢谢

@Edit 下面的代码更好吗?

-(id) initWithID:(NSInteger)id CarYear:(NSString *)year {
    if (self = [super init]) {
        [self setIsCurrentCar:NO];
        [self setID:id];
        [self setCarYear:year];
    }
    return self;
}
4

4 回答 4

9

虽然您的代码没问题,但我会以相反的顺序构造 init-calls,其中最详细的一个是指定的初始化程序,而更一般的调用会冒泡一些默认值:

-(id) initWithID:(NSInteger)id 
         CarYear:(NSString *)year 
{
    if(self = [super init]) {
        _year = year;
        _id = id;
    }
    return self;
}

-(id)initWithID:(NSInteger)id 
{
    return [self initWithID:id CarYear:@"unset"];
}

-(id)init 
{
    return [self initWithID:0];
}

如果调用更通用的初始化程序之一会产生非法状态,则可以改为抛出错误以禁止使用它。

让我们假设,一辆车需要有一个 ID,但不是一年。可以使用initWithID,但是使用init会导致状态不一致,所以我们要强制不使用它:

-(id)init 
{
    [NSException raise:NSInternalInconsistencyException 
                format:@"You must use -initWithID: or -initWithID:CarYear:", NSStringFromSelector(_cmd)];
    return nil;
}

  • 在这段代码中,self 被设置了 3 次。有更好的解决方案吗?

看上面

  • 我在这段代码中有内存泄漏吗?(使用 ARC)

不,一切都很好

  • 我是否必须始终检查 if(self = ...) 或者它是冗余代码?

正如我向您展示的那样:您可以在链中调用不同的 init 方法。只有该链中的最后一个需要执行该操作。


-(id) initWithID:(NSInteger)id CarYear:(NSString *)year {
    if (self = [super init]) {
        [self setIsCurrentCar:NO];
        [self setID:id];
        [self setCarYear:year];
    }
    return self;
}

您不应该在 init-methods 中对 self 使用 setter,请参阅 Apple 的文档

于 2012-12-21T19:39:46.073 回答
3

我想知道上面的代码在结构上是正确的。

是的。我看不出有什么问题。

在这段代码中,self 被设置了 3 次。有更好的解决方案吗?

这很正常。我不会费心去改变它。

我在这段代码中有内存泄漏吗?(使用 ARC)

不。

我是否必须始终检查 if (self = ...) 还是它是冗余代码?

你不必这样做但你绝对应该这样做。有关详细信息,请参阅此问题

于 2012-12-21T19:06:19.783 回答
2

看起来您有一个强制初始化变量和两个实际上是可选的。

我建议init为 ID 和 carYear 实现一个方法和两个 @property()。这减少了初始化器的数量并更好地反映了类的使用约定。

于 2012-12-22T03:45:26.117 回答
1

据我所知......tried to create overloads for Initialization这个语句不应该在这里使用。

通常overload意味着同名多个参数,但在 obj-c 中我们不遵循这一点。在 obj-c 中,通过命名参数来伪造重载。

所以这里有 3 组不同的代码,每组都被称为其他方法。而且您没有内存泄漏,因为您没有为同一个对象分配三次内存,而是在初始化它。

于 2012-12-21T19:53:43.770 回答