Objective-C多个嵌套的initWith用于自定义类

Nar*_*ehM 5 memory-leaks objective-c ios automatic-ref-counting

我对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;
}
Run Code Online (Sandbox Code Playgroud)

让我们说一下,我称之为-(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;
}
Run Code Online (Sandbox Code Playgroud)

Vik*_*ica 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];
}
Run Code Online (Sandbox Code Playgroud)

如果调用一个更通用的初始化程序会产生非法状态,你可以抛出一个错误来禁止使用它.

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

-(id)init 
{
    [NSException raise:NSInternalInconsistencyException 
                format:@"You must use -initWithID: or -initWithID:CarYear:", NSStringFromSelector(_cmd)];
    return nil;
}
Run Code Online (Sandbox Code Playgroud)
  • 在此代码中,self设置为3次.有更好的解决方案吗?

往上看

  • 我的代码中是否有内存泄漏?(使用ARC)

不,一切都很好

  • 我是否必须检查是否(se​​lf = ...)或者它是冗余代码?

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


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

你不应该在init-methods中使用自己的setter,参见Apple的文档.