Objective c 目标C中设计的初始值设定项是如何工作的?

Objective c 目标C中设计的初始值设定项是如何工作的?,objective-c,Objective C,我一直在读这个问题,不明白它遇到的问题。 从我读到的和理解的。每个类都有自己设计的初始值设定项。 在这种情况下,如果一个类有多个初始值设定项。假设我有一个像这样的“Shape.h”类 - (id) init { return [self initWithHeight: 0]; } - (id) initWithHeight: (int) h { return [self initWithHeight:h withWidth:0]; } - (id) initWithHeig

我一直在读这个问题,不明白它遇到的问题。

从我读到的和理解的。每个类都有自己设计的初始值设定项。 在这种情况下,如果一个类有多个初始值设定项。假设我有一个像这样的“Shape.h”类

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

- (id) initWithHeight: (int) h
{
    return [self initWithHeight:h withWidth:0];
}

- (id) initWithHeight: (int) h withWidth: (int) w
{
    if(self = [super init]); //since the superclass is NSObject, I use init as designated initializer
    {
        [self setHeight:h];
        [self setWidth:w];
    }
return self
}
- (id) initWithHeight: (int) h withWidth: (int) w
{
    return [self initWithHeight: h withWidth: w withColor:nil];
}

- (id) initWithHeight: (int) h withWidth: (int) w withColor: (NSString *) c
{
    if(self = [super initWithHeight:h andWidth:w])
    {
        [self setHeight:h];
        [self setWidth:w];
        [self setColor:c];
    }
return self;
}
我从“Shape.h”类中派生了一个名为“Rectangle.h”的新类。 因为我将“Shape.h”类指定为“-(id)initWithHeight:(int)h和witdh:(int)w”,这意味着我需要将它用于“Rectangle.h”类中的[super init],对吗?它变成这样

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

- (id) initWithHeight: (int) h
{
    return [self initWithHeight:h withWidth:0];
}

- (id) initWithHeight: (int) h withWidth: (int) w
{
    if(self = [super init]); //since the superclass is NSObject, I use init as designated initializer
    {
        [self setHeight:h];
        [self setWidth:w];
    }
return self
}
- (id) initWithHeight: (int) h withWidth: (int) w
{
    return [self initWithHeight: h withWidth: w withColor:nil];
}

- (id) initWithHeight: (int) h withWidth: (int) w withColor: (NSString *) c
{
    if(self = [super initWithHeight:h andWidth:w])
    {
        [self setHeight:h];
        [self setWidth:w];
        [self setColor:c];
    }
return self;
}
在“Rectangle.h”中,我覆盖指定为init的super(即Shape.h),并对其进行定制,使其适合指定为“Rectangle.h”的类。这种工作方式是否正确且不会导致循环?如果是这样的话,有人能在我发布的链接中向我解释一下,如果我使用[super init]而不遵循指定为init的超类,为什么它会循环


如果我造成任何混乱,我很抱歉。我不能很好地理解这个概念。

你的代码似乎是正确的,你试过了吗? 指定的初始值设定项是“最完整”的初始值设定项,所有其他初始值设定项都应使用该初始值设定项。这是由矩形类和形状类完成的。 因此,在矩形初始化中要做的是使用超级(形状)初始值设定项初始化类。然后检查self是否正确(super可能会出于任何原因返回nil,例如,您的w/h参数不正确;但是对于Shape,情况并非如此)。然后指定正确的颜色。 您不应该做的是重新指定高度和宽度,因为形状初始值设定项已经这样做了。只有当您的新类需要重写其super的设置时(无论是什么原因),这样做才有意义。 因此,您的代码是正确的,但请删除两组:



        [self setHeight:h];
        [self setWidth:w];

因此,如果我在“Rectangle.h”类中使用指定的init,它将调用超级init,并使用指定为init的超级类设置高度和宽度的值。将值传递给当前类(子类),然后我将color的值分配给子类“Rectangle.h”。所以我只覆盖指定为init的超类的方法在我的代码中是正确的,对吗?如果这是正确的,我可以将“Rectangle.h”self=[super initWithHeight:(int)h和witdth:w]替换为self=[super init],因为这个超类最终会将它命名为init。不,这是不正确的。事实上,如果Rectangle initWithHeight:Width:Color调用[super init],那么反过来将调用Rectangle initWithHeight:Width:Width,这将调用Rectangle initWithHeight:Width:Color,从而导致循环。此外,您不会利用形状的initWithHeight:andWidth执行的完整初始化。因此,要非常小心,并始终遵循这条规则(来自苹果的“Objective-C编程语言”):一般原则:类中指定的初始值设定项必须通过发送给super的消息调用超类中指定的初始值设定项。这两行之间的区别是什么?[super init]和[super initWithHeight:AndWidth:]。为什么后者不会导致循环?我的意思是,如果我使用[super init],不是会调用Shape.h initWithHeight->initWithHeight:andWidth使它们相同吗?问题是,如果调用[super init],你会调用Shape的init,对吗?但Shape的init将调用[self initWithHeight:0],但“self”是矩形。所以它将调用矩形的initWithHeight:它不存在,所以将调用形状的initWithHeight:。但是Shape的initWithHeight:调用[self initWithHeight:h withWidth:0]但是self是矩形的,所以它会调用矩形的initWithHeight:withWidth:调用[self initWithHeigth:withWidth:withColor:]调用方==>循环度。谢谢,我终于明白了为什么它会导致循环度。Self始终指向当前类,无论我是否从超类调用方法(因为超类调用Self调用当前类矩形)。