为什么指定的初始化程序不能在其基类中调用辅助初始化程序? [英] Why can't a designated initializer call a secondary initializer in its base class?

查看:243
本文介绍了为什么指定的初始化程序不能在其基类中调用辅助初始化程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据文档,Objective-C中一个类的指定初始化器必须调用其基类的指定初始化器。

According to the documentation, a class's designated initializer in Objective-C must call the designated initializer of its base class.

另一个规则是辅助初始化器必须调用

Another rule is that secondary initializers must call the designated initializer of their own class.

但是如果遵循第二条规则,为什么指定的初始化器不能调用其基类中的辅助初始化器?这个基本的辅助初始化器最终会调用它自己的级别的DI,所以对象仍然会被正确初始化,对吗?

But if the second rule is followed, why can't a designated initializer call a secondary initializer in its base class? This base secondary initializer will ultimately call its own level's D.I., so the object will still be properly initialized, right?

差别似乎是谁选择缺省变量的默认值 - - 你或你的基类。

The difference seems to be who chooses defaults for missing variables -- you or your base class.

推荐答案

让我们考虑 NSSet 。它有一个指定的初始化器:

Let's consider NSSet. It has a designated initializer:

- (id)initWithObjects:(const id *)objects count:(NSUInteger)cnt {
   // initialization code here
   return self;
}

它还有一些辅助初始化器,像这样:

It also has some secondary initializers, like this one:

- (id)initWithArray:(NSArray *)array {
    NSUInteger count = array.count;
    id objects[count];
    [array getObjects:objects range:NSMakeRange(0, count)];
    return [self initWithObjects:objects count:count];
}

现在你想要一个 NSSet 将自动拒绝字符串Bob。所以你尽职尽责地覆盖你的子类中指定的初始化器,但你调用super的辅助初始化器之一:

Now you want a subclass of NSSet that automatically rejects the string "Bob". So you dutifully override the designated initializer in your subclass, but you call one of super's secondary initializers:

@implementation BobRejectingSet

- (id)initWithObjects:(const id *)objects count:(NSUInteger)count {
    NSMutableArray *array = [[NSMutableArray alloc] initWithCount:count];
    for (NSUInteger i = 0; i < count; ++i) {
        if (![objects[i] isEqual:@"Bob"]) {
            [array addObject:objects[i]];
        }
    }
    return [super initWithArray:array];
}

执行此操作时会发生什么:

What happens when you do this:

BobRejectingSet *noBobs = [[BobRejectingSet alloc] initWithArray:someObjects];

,程序调用 - [NSSet initWithArray:] ,它调用指定的初始化程序 initWithObjects:count:。你覆盖指定的初始化程序,所以它调用你的方法。你的方法过滤出Bobs,然后调用super的辅助初始化器, initWithArray: ...它会转向,并再次调用指定的初始化器。无限递归。堆栈溢出。

Since you didn't override initWithArray:, the program calls -[NSSet initWithArray:], which calls the designated initializer, initWithObjects:count:. You overrode the designated initializer, so it calls your method. Your method filters out the Bobs, and then calls super's secondary initializer, initWithArray:… which turns around and calls your designated initializer override again. Unlimited recursion. Stack overflow. You get the segmentation-violation-core-dumped blues.

这就是为什么你总是使用super的指定初始化器。

That's why you always use super's designated initializer.

这篇关于为什么指定的初始化程序不能在其基类中调用辅助初始化程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆