我应该将调用我班级指定初始化程序的结果分配给自己吗?

时间:2011-12-08 18:38:59

标签: objective-c initialization core-plot

我正在阅读核心情节的来源,并在CPTColor

中遇到了这段代码
-(id)initWithCGColor:(CGColorRef)newCGColor
{
    if ( (self = [super init]) ) {            
        CGColorRetain(newCGColor);
        cgColor = newCGColor;
    }
    return self;
}

-(id)initWithComponentRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha
{
    CGFloat colorComponents[4];
    colorComponents[0] = red;
    colorComponents[1] = green;
    colorComponents[2] = blue;
    colorComponents[3] = alpha;
    CGColorRef color = CGColorCreate([CPTColorSpace genericRGBSpace].cgColorSpace, colorComponents);
    [self initWithCGColor:color];
    CGColorRelease(color);
    return self;
}

如果[self initWithCGColor:color];导致initWithCGColor的超类为自己分配不同的值,那么该新值是否会从initWithComponentRed:green:blue:alpha:返回?

换句话说,两个init方法中的self是同一个变量两个不同的变量吗?

3 个答案:

答案 0 :(得分:3)

此设置可能很脆弱,而Joe的建议是,在返回该值之前在self中指定initWithComponentRed:...将修复它。

每个方法都会获得一个参数self,该参数指向它所调用的实例。该参数的行为与任何其他变量一样;这没什么特别的。这就是为什么可以分配self,以及为什么必须在初始化器中使用明确的return

当您发送[super init]时,您正在使用超类的init方法版本,但当前实例仍将作为self传递。由于Objective-C中的初始化程序被允许销毁它们接收的对象并创建并返回一个新对象,* self = [super init]中的initWithColor:可能与指向的对象不同。 self回到initWithComponentRed:...

如果发生这种情况,由于您未重新指定self指向新的,正确初始化的对象,您将从initWithComponentRed:...返回未初始化的对象

如果您的超类可以进行我所描述的替换,这只是一个实际问题,但也没有理由,AFAIK,不进行重新分配。


*例如,集合会这样做,因为他们不知道在alloc时间需要多大的数据;我相信NSNumber也会这样做,因为它为表示小整数的实例缓存了值。

答案 1 :(得分:2)

如果self要更改,则为否(例如,如果您要实现颜色缓存)initWithComponentRed:green:blue:alpha:将返回错误的对象,除非代码更改为:

    ...
    self = [self initWithCGColor:color];
    CGColorRelease(color);
    return self;
}

答案 2 :(得分:0)

self始终引用同一个对象。 它不是一个“变量”,而是一个语言关键词。如果一个初始值设定项在另一个之后被调用,则该对象只是被改变了。

注意:否则,你的倾城课会有“分裂的个性”;-)。